Skip to content

Commit 4080bca

Browse files
committed
refactor: Enhance docs, add tests in AVLSimple
1 parent bca8d0e commit 4080bca

File tree

2 files changed

+142
-31
lines changed

2 files changed

+142
-31
lines changed

src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java

Lines changed: 76 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,38 @@
11
package com.thealgorithms.datastructures.trees;
22

3-
/*
4-
* Avl is algo that balance itself while adding new alues to tree
5-
* by rotating branches of binary tree and make itself Binary seaarch tree
6-
* there are four cases which has to tackle
7-
* rotating - left right ,left left,right right,right left
8-
9-
Test Case:
10-
11-
AVLTree tree=new AVLTree();
12-
tree.insert(20);
13-
tree.insert(25);
14-
tree.insert(30);
15-
tree.insert(10);
16-
tree.insert(5);
17-
tree.insert(15);
18-
tree.insert(27);
19-
tree.insert(19);
20-
tree.insert(16);
21-
22-
tree.display();
23-
24-
25-
26-
27-
*/
28-
3+
/**
4+
* The AVLSimple class implements an AVL Tree, a self-balancing binary search tree.
5+
* It maintains the balance of the tree using rotations during insertion to ensure that
6+
* the heights of the two child subtrees of any node differ by at most one.
7+
*
8+
* An AVL Tree performs the following operations:
9+
* - Insertion: Adds a new node while maintaining the AVL property.
10+
* - Display: Outputs the structure of the tree.
11+
*
12+
* The AVL tree balances itself in four main cases during insertion:
13+
* 1. Left-Left (LL) Case: Right rotation is performed.
14+
* 2. Right-Right (RR) Case: Left rotation is performed.
15+
* 3. Right-Left (RL) Case: Right rotation followed by left rotation.
16+
* 4. Left-Right (LR) Case: Left rotation followed by right rotation.
17+
*
18+
* Example usage:
19+
* <pre>
20+
* AVLSimple tree = new AVLSimple();
21+
* tree.insert(20);
22+
* tree.insert(25);
23+
* tree.insert(30);
24+
* tree.insert(10);
25+
* tree.insert(5);
26+
* tree.insert(15);
27+
* tree.insert(27);
28+
* tree.insert(19);
29+
* tree.insert(16);
30+
* tree.display();
31+
* </pre>
32+
*/
2933
public class AVLSimple {
3034

31-
private class Node {
32-
35+
static class Node {
3336
int data;
3437
int height;
3538
Node left;
@@ -43,6 +46,11 @@ private class Node {
4346

4447
private Node root;
4548

49+
/**
50+
* Inserts a new value into the AVL Tree.
51+
*
52+
* @param data the value to be inserted
53+
*/
4654
public void insert(int data) {
4755
this.root = insert(this.root, data);
4856
}
@@ -53,12 +61,14 @@ private Node insert(Node node, int item) {
5361
}
5462
if (node.data > item) {
5563
node.left = insert(node.left, item);
56-
}
57-
if (node.data < item) {
64+
} else if (node.data < item) {
5865
node.right = insert(node.right, item);
66+
} else {
67+
return node;
5968
}
6069
node.height = Math.max(height(node.left), height(node.right)) + 1;
6170
int bf = bf(node);
71+
6272
// LL case
6373
if (bf > 1 && item < node.left.data) {
6474
return rightRotate(node);
@@ -81,9 +91,12 @@ private Node insert(Node node, int item) {
8191
return node;
8292
}
8393

94+
/**
95+
* Displays the structure of the AVL Tree in a readable format.
96+
*/
8497
public void display() {
8598
this.display(this.root);
86-
System.out.println(this.root.height);
99+
System.out.println("Tree Height: " + this.root.height);
87100
}
88101

89102
private void display(Node node) {
@@ -108,20 +121,38 @@ private void display(Node node) {
108121
}
109122
}
110123

124+
/**
125+
* Returns the height of the AVL Tree.
126+
*
127+
* @param node the root node of the AVL Tree
128+
* @return the height of the AVL Tree
129+
*/
111130
private int height(Node node) {
112131
if (node == null) {
113132
return 0;
114133
}
115134
return node.height;
116135
}
117136

137+
/**
138+
* Returns the balance factor of the AVL Tree.
139+
*
140+
* @param node the root node of the AVL Tree
141+
* @return the balance factor of the AVL Tree
142+
*/
118143
private int bf(Node node) {
119144
if (node == null) {
120145
return 0;
121146
}
122147
return height(node.left) - height(node.right);
123148
}
124149

150+
/**
151+
* Performs a right rotation on the AVL Tree.
152+
*
153+
* @param c the root node of the AVL Tree
154+
* @return the new root node of the AVL Tree
155+
*/
125156
private Node rightRotate(Node c) {
126157
Node b = c.left;
127158
Node t3 = b.right;
@@ -133,6 +164,12 @@ private Node rightRotate(Node c) {
133164
return b;
134165
}
135166

167+
/**
168+
* Performs a left rotation on the AVL Tree.
169+
*
170+
* @param c the root node of the AVL Tree
171+
* @return the new root node of the AVL Tree
172+
*/
136173
private Node leftRotate(Node c) {
137174
Node b = c.right;
138175
Node t3 = b.left;
@@ -143,4 +180,12 @@ private Node leftRotate(Node c) {
143180
b.height = Math.max(height(b.left), height(b.right)) + 1;
144181
return b;
145182
}
183+
184+
public int getHeight() {
185+
return this.root.height;
186+
}
187+
188+
public Node getRoot() {
189+
return this.root;
190+
}
146191
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.thealgorithms.datastructures.trees;
2+
3+
import static org.junit.jupiter.api.Assertions.*;
4+
5+
import org.junit.jupiter.api.BeforeEach;
6+
import org.junit.jupiter.api.Test;
7+
8+
public class AVLSimpleTest {
9+
10+
private AVLSimple tree;
11+
12+
@BeforeEach
13+
public void setup() {
14+
tree = new AVLSimple();
15+
}
16+
17+
@Test
18+
public void testInsertAndDisplay() {
19+
tree.insert(20);
20+
tree.insert(30);
21+
tree.insert(10);
22+
tree.insert(5);
23+
tree.insert(15);
24+
25+
// The output is not directly testable since display prints to console,
26+
// so we'll check the height of the tree to verify that balancing occurred
27+
assertEquals(3, tree.getHeight());
28+
}
29+
30+
@Test
31+
public void testInsertAndBalance() {
32+
tree.insert(10);
33+
tree.insert(20);
34+
tree.insert(30); // This will cause a left rotation
35+
assertEquals(20, tree.getRoot().data);
36+
assertEquals(10, tree.getRoot().left.data);
37+
assertEquals(30, tree.getRoot().right.data);
38+
}
39+
40+
@Test
41+
public void testInsertMultipleValues() {
42+
int[] values = {30, 20, 40, 10, 25, 35, 50};
43+
for (int value : values) {
44+
tree.insert(value);
45+
}
46+
assertEquals(30, tree.getRoot().data);
47+
assertEquals(20, tree.getRoot().left.data);
48+
assertEquals(40, tree.getRoot().right.data);
49+
assertEquals(10, tree.getRoot().left.left.data);
50+
assertEquals(25, tree.getRoot().left.right.data);
51+
assertEquals(35, tree.getRoot().right.left.data);
52+
assertEquals(50, tree.getRoot().right.right.data);
53+
}
54+
55+
@Test
56+
public void testHeightAfterInsertions() {
57+
tree.insert(50);
58+
tree.insert(30);
59+
tree.insert(20);
60+
tree.insert(40);
61+
tree.insert(70);
62+
tree.insert(60);
63+
tree.insert(80);
64+
assertEquals(3, tree.getHeight());
65+
}
66+
}

0 commit comments

Comments
 (0)