diff --git a/DIRECTORY.md b/DIRECTORY.md index 0c9aeca4e59a..4be46b43cf71 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -597,6 +597,7 @@ * [UnionFind](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/UnionFind.java) * [UpperBound](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/UpperBound.java) * slidingwindow + * [LongestSubarrayWithSumLessOrEqualToK](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/slidingwindow/LongestSubarrayWithSumLessOrEqualToK.java) * [LongestSubstringWithoutRepeatingCharacters](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/slidingwindow/LongestSubstringWithoutRepeatingCharacters.java) * [MaxSumKSizeSubarray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarray.java) * [MinSumKSizeSubarray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/slidingwindow/MinSumKSizeSubarray.java) @@ -909,6 +910,7 @@ * [StackArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/StackArrayTest.java) * [StackOfLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/StackOfLinkedListTest.java) * trees + * [AVLSimpleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/AVLSimpleTest.java) * [BinaryTreeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BinaryTreeTest.java) * [BoundaryTraversalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BoundaryTraversalTest.java) * [BSTFromSortedArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BSTFromSortedArrayTest.java) @@ -1228,6 +1230,7 @@ * [UnionFindTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/UnionFindTest.java) * [UpperBoundTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/UpperBoundTest.java) * slidingwindow + * [LongestSubarrayWithSumLessOrEqualToKTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/slidingwindow/LongestSubarrayWithSumLessOrEqualToKTest.java) * [LongestSubstringWithoutRepeatingCharactersTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/slidingwindow/LongestSubstringWithoutRepeatingCharactersTest.java) * [MaxSumKSizeSubarrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/slidingwindow/MaxSumKSizeSubarrayTest.java) * [MinSumKSizeSubarrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/slidingwindow/MinSumKSizeSubarrayTest.java) diff --git a/src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java b/src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java index e0309122cc12..bd6fcc04738a 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java @@ -1,35 +1,38 @@ package com.thealgorithms.datastructures.trees; -/* -* Avl is algo that balance itself while adding new alues to tree -* by rotating branches of binary tree and make itself Binary seaarch tree -* there are four cases which has to tackle -* rotating - left right ,left left,right right,right left - -Test Case: - -AVLTree tree=new AVLTree(); - tree.insert(20); - tree.insert(25); - tree.insert(30); - tree.insert(10); - tree.insert(5); - tree.insert(15); - tree.insert(27); - tree.insert(19); - tree.insert(16); - - tree.display(); - - - - -*/ - +/** + * The AVLSimple class implements an AVL Tree, a self-balancing binary search tree. + * It maintains the balance of the tree using rotations during insertion to ensure that + * the heights of the two child subtrees of any node differ by at most one. + * + * An AVL Tree performs the following operations: + * - Insertion: Adds a new node while maintaining the AVL property. + * - Display: Outputs the structure of the tree. + * + * The AVL tree balances itself in four main cases during insertion: + * 1. Left-Left (LL) Case: Right rotation is performed. + * 2. Right-Right (RR) Case: Left rotation is performed. + * 3. Right-Left (RL) Case: Right rotation followed by left rotation. + * 4. Left-Right (LR) Case: Left rotation followed by right rotation. + * + * Example usage: + *
+ * AVLSimple tree = new AVLSimple(); + * tree.insert(20); + * tree.insert(25); + * tree.insert(30); + * tree.insert(10); + * tree.insert(5); + * tree.insert(15); + * tree.insert(27); + * tree.insert(19); + * tree.insert(16); + * tree.display(); + *+ */ public class AVLSimple { - private class Node { - + static class Node { int data; int height; Node left; @@ -43,6 +46,11 @@ private class Node { private Node root; + /** + * Inserts a new value into the AVL Tree. + * + * @param data the value to be inserted + */ public void insert(int data) { this.root = insert(this.root, data); } @@ -53,12 +61,14 @@ private Node insert(Node node, int item) { } if (node.data > item) { node.left = insert(node.left, item); - } - if (node.data < item) { + } else if (node.data < item) { node.right = insert(node.right, item); + } else { + return node; } node.height = Math.max(height(node.left), height(node.right)) + 1; int bf = bf(node); + // LL case if (bf > 1 && item < node.left.data) { return rightRotate(node); @@ -81,9 +91,12 @@ private Node insert(Node node, int item) { return node; } + /** + * Displays the structure of the AVL Tree in a readable format. + */ public void display() { this.display(this.root); - System.out.println(this.root.height); + System.out.println("Tree Height: " + this.root.height); } private void display(Node node) { @@ -108,6 +121,12 @@ private void display(Node node) { } } + /** + * Returns the height of the AVL Tree. + * + * @param node the root node of the AVL Tree + * @return the height of the AVL Tree + */ private int height(Node node) { if (node == null) { return 0; @@ -115,6 +134,12 @@ private int height(Node node) { return node.height; } + /** + * Returns the balance factor of the AVL Tree. + * + * @param node the root node of the AVL Tree + * @return the balance factor of the AVL Tree + */ private int bf(Node node) { if (node == null) { return 0; @@ -122,6 +147,12 @@ private int bf(Node node) { return height(node.left) - height(node.right); } + /** + * Performs a right rotation on the AVL Tree. + * + * @param c the root node of the AVL Tree + * @return the new root node of the AVL Tree + */ private Node rightRotate(Node c) { Node b = c.left; Node t3 = b.right; @@ -133,6 +164,12 @@ private Node rightRotate(Node c) { return b; } + /** + * Performs a left rotation on the AVL Tree. + * + * @param c the root node of the AVL Tree + * @return the new root node of the AVL Tree + */ private Node leftRotate(Node c) { Node b = c.right; Node t3 = b.left; @@ -143,4 +180,12 @@ private Node leftRotate(Node c) { b.height = Math.max(height(b.left), height(b.right)) + 1; return b; } + + public int getHeight() { + return this.root.height; + } + + public Node getRoot() { + return this.root; + } } diff --git a/src/test/java/com/thealgorithms/datastructures/trees/AVLSimpleTest.java b/src/test/java/com/thealgorithms/datastructures/trees/AVLSimpleTest.java new file mode 100644 index 000000000000..c10829853d59 --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/trees/AVLSimpleTest.java @@ -0,0 +1,66 @@ +package com.thealgorithms.datastructures.trees; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class AVLSimpleTest { + + private AVLSimple tree; + + @BeforeEach + public void setup() { + tree = new AVLSimple(); + } + + @Test + public void testInsertAndDisplay() { + tree.insert(20); + tree.insert(30); + tree.insert(10); + tree.insert(5); + tree.insert(15); + + // The output is not directly testable since display prints to console, + // so we'll check the height of the tree to verify that balancing occurred + assertEquals(3, tree.getHeight()); + } + + @Test + public void testInsertAndBalance() { + tree.insert(10); + tree.insert(20); + tree.insert(30); // This will cause a left rotation + assertEquals(20, tree.getRoot().data); + assertEquals(10, tree.getRoot().left.data); + assertEquals(30, tree.getRoot().right.data); + } + + @Test + public void testInsertMultipleValues() { + int[] values = {30, 20, 40, 10, 25, 35, 50}; + for (int value : values) { + tree.insert(value); + } + assertEquals(30, tree.getRoot().data); + assertEquals(20, tree.getRoot().left.data); + assertEquals(40, tree.getRoot().right.data); + assertEquals(10, tree.getRoot().left.left.data); + assertEquals(25, tree.getRoot().left.right.data); + assertEquals(35, tree.getRoot().right.left.data); + assertEquals(50, tree.getRoot().right.right.data); + } + + @Test + public void testHeightAfterInsertions() { + tree.insert(50); + tree.insert(30); + tree.insert(20); + tree.insert(40); + tree.insert(70); + tree.insert(60); + tree.insert(80); + assertEquals(3, tree.getHeight()); + } +}