1
1
package com .thealgorithms .datastructures .trees ;
2
2
3
+ import java .util .ArrayList ;
4
+ import java .util .List ;
5
+
6
+ /**
7
+ * Represents an AVL Tree, a self-balancing binary search tree.
8
+ * In an AVL tree, the heights of the two child subtrees of any node
9
+ * differ by at most one. If they differ by more than one at any time,
10
+ * rebalancing is performed to restore this property.
11
+ */
3
12
public class AVLTree {
4
13
5
14
private Node root ;
6
15
7
- private class Node {
8
-
16
+ private static class Node {
9
17
private int key ;
10
18
private int balance ;
11
19
private int height ;
@@ -17,8 +25,18 @@ private class Node {
17
25
key = k ;
18
26
parent = p ;
19
27
}
28
+
29
+ public Integer getBalance () {
30
+ return balance ;
31
+ }
20
32
}
21
33
34
+ /**
35
+ * Inserts a new key into the AVL tree.
36
+ *
37
+ * @param key the key to be inserted
38
+ * @return {@code true} if the key was inserted, {@code false} if the key already exists
39
+ */
22
40
public boolean insert (int key ) {
23
41
if (root == null ) {
24
42
root = new Node (key , null );
@@ -31,7 +49,6 @@ public boolean insert(int key) {
31
49
}
32
50
33
51
parent = n ;
34
-
35
52
boolean goLeft = n .key > key ;
36
53
n = goLeft ? n .left : n .right ;
37
54
@@ -49,8 +66,32 @@ public boolean insert(int key) {
49
66
return true ;
50
67
}
51
68
69
+ /**
70
+ * Deletes a key from the AVL tree.
71
+ *
72
+ * @param delKey the key to be deleted
73
+ */
74
+ public void delete (int delKey ) {
75
+ if (root == null ) {
76
+ return ;
77
+ }
78
+
79
+ // Find the node to be deleted
80
+ Node node = root ;
81
+ Node child = root ;
82
+ while (child != null ) {
83
+ node = child ;
84
+ child = delKey >= node .key ? node .right : node .left ;
85
+ if (delKey == node .key ) {
86
+ delete (node );
87
+ return ;
88
+ }
89
+ }
90
+ }
91
+
52
92
private void delete (Node node ) {
53
93
if (node .left == null && node .right == null ) {
94
+ // Leaf node
54
95
if (node .parent == null ) {
55
96
root = null ;
56
97
} else {
@@ -64,6 +105,8 @@ private void delete(Node node) {
64
105
}
65
106
return ;
66
107
}
108
+
109
+ // Node has one or two children
67
110
Node child ;
68
111
if (node .left != null ) {
69
112
child = node .left ;
@@ -80,26 +123,49 @@ private void delete(Node node) {
80
123
delete (child );
81
124
}
82
125
83
- public void delete (int delKey ) {
84
- if (root == null ) {
85
- return ;
126
+ /**
127
+ * Returns a list of balance factors for each node in the tree.
128
+ *
129
+ * @return a list of integers representing the balance factors of the nodes
130
+ */
131
+ public List <Integer > returnBalance () {
132
+ List <Integer > balances = new ArrayList <>();
133
+ returnBalance (root , balances );
134
+ return balances ;
135
+ }
136
+
137
+ private void returnBalance (Node n , List <Integer > balances ) {
138
+ if (n != null ) {
139
+ returnBalance (n .left , balances );
140
+ balances .add (n .getBalance ());
141
+ returnBalance (n .right , balances );
86
142
}
87
- Node node = root ;
88
- Node child = root ;
143
+ }
89
144
90
- while (child != null ) {
91
- node = child ;
92
- child = delKey >= node .key ? node .right : node .left ;
93
- if (delKey == node .key ) {
94
- delete (node );
95
- return ;
96
- }
145
+ /**
146
+ * Searches for a key in the AVL tree.
147
+ *
148
+ * @param key the key to be searched
149
+ * @return true if the key is found, false otherwise
150
+ */
151
+ public boolean search (int key ) {
152
+ Node result = searchHelper (this .root , key );
153
+ return result != null ;
154
+ }
155
+
156
+ private Node searchHelper (Node root , int key ) {
157
+ if (root == null || root .key == key ) {
158
+ return root ;
97
159
}
160
+
161
+ if (root .key > key ) {
162
+ return searchHelper (root .left , key );
163
+ }
164
+ return searchHelper (root .right , key );
98
165
}
99
166
100
167
private void rebalance (Node n ) {
101
168
setBalance (n );
102
-
103
169
if (n .balance == -2 ) {
104
170
if (height (n .left .left ) >= height (n .left .right )) {
105
171
n = rotateRight (n );
@@ -143,7 +209,6 @@ private Node rotateLeft(Node a) {
143
209
}
144
210
145
211
setBalance (a , b );
146
-
147
212
return b ;
148
213
}
149
214
@@ -169,7 +234,6 @@ private Node rotateRight(Node a) {
169
234
}
170
235
171
236
setBalance (a , b );
172
-
173
237
return b ;
174
238
}
175
239
@@ -197,53 +261,9 @@ private void setBalance(Node... nodes) {
197
261
}
198
262
}
199
263
200
- public void printBalance () {
201
- printBalance (root );
202
- }
203
-
204
- private void printBalance (Node n ) {
205
- if (n != null ) {
206
- printBalance (n .left );
207
- System .out .printf ("%s " , n .balance );
208
- printBalance (n .right );
209
- }
210
- }
211
-
212
264
private void reheight (Node node ) {
213
265
if (node != null ) {
214
266
node .height = 1 + Math .max (height (node .left ), height (node .right ));
215
267
}
216
268
}
217
-
218
- public boolean search (int key ) {
219
- Node result = searchHelper (this .root , key );
220
- return result != null ;
221
- }
222
-
223
- private Node searchHelper (Node root , int key ) {
224
- // root is null or key is present at root
225
- if (root == null || root .key == key ) {
226
- return root ;
227
- }
228
-
229
- // key is greater than root's key
230
- if (root .key > key ) {
231
- return searchHelper (root .left , key ); // call the function on the node's left child
232
- }
233
- // key is less than root's key then
234
- // call the function on the node's right child as it is greater
235
- return searchHelper (root .right , key );
236
- }
237
-
238
- public static void main (String [] args ) {
239
- AVLTree tree = new AVLTree ();
240
-
241
- System .out .println ("Inserting values 1 to 10" );
242
- for (int i = 1 ; i < 10 ; i ++) {
243
- tree .insert (i );
244
- }
245
-
246
- System .out .print ("Printing balance: " );
247
- tree .printBalance ();
248
- }
249
269
}
0 commit comments