11package com .thealgorithms .datastructures .trees ;
22
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+ */
312public class AVLTree {
413
514 private Node root ;
615
7- private class Node {
8-
16+ private static class Node {
917 private int key ;
1018 private int balance ;
1119 private int height ;
@@ -17,8 +25,18 @@ private class Node {
1725 key = k ;
1826 parent = p ;
1927 }
28+
29+ public Integer getBalance () {
30+ return balance ;
31+ }
2032 }
2133
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+ */
2240 public boolean insert (int key ) {
2341 if (root == null ) {
2442 root = new Node (key , null );
@@ -31,7 +49,6 @@ public boolean insert(int key) {
3149 }
3250
3351 parent = n ;
34-
3552 boolean goLeft = n .key > key ;
3653 n = goLeft ? n .left : n .right ;
3754
@@ -49,8 +66,32 @@ public boolean insert(int key) {
4966 return true ;
5067 }
5168
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+
5292 private void delete (Node node ) {
5393 if (node .left == null && node .right == null ) {
94+ // Leaf node
5495 if (node .parent == null ) {
5596 root = null ;
5697 } else {
@@ -64,6 +105,8 @@ private void delete(Node node) {
64105 }
65106 return ;
66107 }
108+
109+ // Node has one or two children
67110 Node child ;
68111 if (node .left != null ) {
69112 child = node .left ;
@@ -80,26 +123,49 @@ private void delete(Node node) {
80123 delete (child );
81124 }
82125
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 );
86142 }
87- Node node = root ;
88- Node child = root ;
143+ }
89144
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 ;
97159 }
160+
161+ if (root .key > key ) {
162+ return searchHelper (root .left , key );
163+ }
164+ return searchHelper (root .right , key );
98165 }
99166
100167 private void rebalance (Node n ) {
101168 setBalance (n );
102-
103169 if (n .balance == -2 ) {
104170 if (height (n .left .left ) >= height (n .left .right )) {
105171 n = rotateRight (n );
@@ -143,7 +209,6 @@ private Node rotateLeft(Node a) {
143209 }
144210
145211 setBalance (a , b );
146-
147212 return b ;
148213 }
149214
@@ -169,7 +234,6 @@ private Node rotateRight(Node a) {
169234 }
170235
171236 setBalance (a , b );
172-
173237 return b ;
174238 }
175239
@@ -197,53 +261,9 @@ private void setBalance(Node... nodes) {
197261 }
198262 }
199263
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-
212264 private void reheight (Node node ) {
213265 if (node != null ) {
214266 node .height = 1 + Math .max (height (node .left ), height (node .right ));
215267 }
216268 }
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- }
249269}
0 commit comments