From 4e4e7f2c19cfc2627b3efde341bc403a29b38993 Mon Sep 17 00:00:00 2001 From: Shree Harish S Date: Thu, 3 Oct 2024 20:03:26 +0530 Subject: [PATCH 01/10] added treap class --- .../datastructures/trees/Treap.java | 333 ++++++++++++++++++ .../datastructures/trees/TreapTest.java | 74 ++++ 2 files changed, 407 insertions(+) create mode 100644 src/main/java/com/thealgorithms/datastructures/trees/Treap.java create mode 100644 src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java diff --git a/src/main/java/com/thealgorithms/datastructures/trees/Treap.java b/src/main/java/com/thealgorithms/datastructures/trees/Treap.java new file mode 100644 index 000000000000..547214bfb107 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/Treap.java @@ -0,0 +1,333 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.Random; + +/** + * Treap -> Tree + Heap + * Also called as cartesian tree + * + * @see + * + */ + +public class Treap { + + static class TreapNode { + /** + * TreapNode class defines the individual nodes in the Treap + * + * value -> holds the value of the node. + * Binary Search Tree is built based on value. + * + * priority -> holds the priority of the node. + * Heaps are maintained based on priority. + * It is randomly assigned + * + * size -> holds the size of the subtree with current node as root + * + * left -> holds the left subtree + * right -> holds the right subtree + */ + public int value; + private int priority, size; + public TreapNode left, right; + + public TreapNode(int value, int priority) { + this.value = value; + this.priority = priority; + this.size = 1; + this.left = this.right = null; + } + + /** + * updateSize -> updates the subtree size of the current node + */ + private void updateSize() { + this.size = 1; + if (this.left != null) this.size += this.left.size; + if (this.right != null) this.size += this.right.size; + } + } + + /** + * root -> holds the root node in the Treap + * random -> to generate random priority for the nodes in the Treap + */ + private TreapNode root; + private Random random = new Random(); + + /** + * Constructors + * + * Treap() -> create an empty Treap + * Treap(int[] nodeValues) -> add the elements given in the array to the Treap + */ + public Treap() { + this.root = null; + } + + public Treap(int[] nodeValues) { + for (int nodeValue : nodeValues) insert(nodeValue); + } + + /** + * merges two Treaps left and right into a single Treap + * + * @param left left Treap + * @param right right Treap + * @return root of merged Treap + */ + private TreapNode merge(TreapNode left, TreapNode right) { + if (left == null) return right; + if (right == null) return left; + + if (left.priority > right.priority) { + left.right = merge(left.right, right); + left.updateSize(); + return left; + } else { + right.left = merge(left, right.left); + right.updateSize(); + return right; + } + } + + /** + * split the Treap into two Treaps where left Treap has nodes <= key and right Treap has nodes > key + * + * @param node root node to be split + * @param key key to compare the nodes + * @return TreapNode array of size 2. + * TreapNode[0] contains the root of left Treap after split + * TreapNode[1] contains the root of right Treap after split + */ + private TreapNode[] split(TreapNode node, int key) { + if (node == null) { + return new TreapNode[] {null, null}; + } + + TreapNode[] result; + + if (node.value <= key) { + result = split(node.right, key); + node.right = result[0]; + node.updateSize(); + result[0] = node; + } else { + result = split(node.left, key); + node.left = result[1]; + node.updateSize(); + result[1] = node; + } + + return result; + } + + /** + * insert a node into the Treap + * + * @param value value to be inserted into the Treap + * @return root of the Treap where the value is inserted + */ + public TreapNode insert(int value) { + if (root == null) { + root = new TreapNode(value, random.nextInt()); + return root; + } + + TreapNode[] splitted = split(root, value); + + TreapNode node = new TreapNode(value, random.nextInt()); + + TreapNode tempMerged = merge(splitted[0], node); + tempMerged.updateSize(); + + TreapNode merged = merge(tempMerged, splitted[1]); + merged.updateSize(); + + root = merged; + + return root; + } + + /** + * delete a value from root if present + * + * @param value value to be deleted from the Treap + * @return root of the Treap where delete has been performed + */ + public TreapNode delete(int value) { + root = deleteNode(root, value); + return root; + } + + private TreapNode deleteNode(TreapNode root, int value) { + if (root == null) return null; + + if (value < root.value) { + root.left = deleteNode(root.left, value); + } else if (value > root.value) { + root.right = deleteNode(root.right, value); + } else { + root = merge(root.left, root.right); + } + + if (root != null) root.updateSize(); + return root; + } + + /** + * print inorder traversal of the Treap + */ + public void inOrder() { + System.out.print("{"); + printInorder(root); + System.out.print("}"); + } + + private void printInorder(TreapNode root) { + if (root == null) return; + printInorder(root.left); + System.out.print(root.value + ","); + printInorder(root.right); + } + + /** + * print preOrder traversal of the Treap + */ + public void preOrder() { + System.out.print("{"); + printPreOrder(root); + System.out.print("}"); + } + + private void printPreOrder(TreapNode root) { + if (root == null) return; + System.out.print(root.value + ","); + printPreOrder(root.left); + printPreOrder(root.right); + } + + /** + * print postOrder traversal of the Treap + */ + public void postOrder() { + System.out.print("{"); + printPostOrder(root); + System.out.print("}"); + } + + private void printPostOrder(TreapNode root) { + if (root == null) return; + printPostOrder(root.left); + printPostOrder(root.right); + System.out.print(root.value + ","); + } + + /** + * Search a value in the Treap + * + * @param value value to be searched for + * @return node containing the value + * null if not found + */ + public TreapNode search(int value) { + return searchVal(root, value); + } + + private TreapNode searchVal(TreapNode root, int value) { + if (root == null) return null; + + if (root.value == value) + return root; + else if (root.value < value) + return searchVal(root.right, value); + else + return searchVal(root.left, value); + } + + /** + * find the lowerBound of a value in the Treap + * + * @param value value for which lowerBound is to be found + * @return node which is the lowerBound of the value passed + */ + public TreapNode lowerBound(int value) { + TreapNode lowerBoundNode = null; + TreapNode current = root; + + while (current != null) { + if (current.value >= value) { + lowerBoundNode = current; + current = current.left; + } else + current = current.right; + } + + return lowerBoundNode; + } + + /** + * find the upperBound of a value in the Treap + * + * @param value value for which upperBound is to be found + * @return node which is the upperBound of the value passed + */ + public TreapNode upperBound(int value) { + TreapNode upperBoundNode = null; + TreapNode current = root; + + while (current != null) { + if (current.value > value) { + upperBoundNode = current; + current = current.left; + } else + current = current.right; + } + + return upperBoundNode; + } + + /** + * returns size of the Treap + */ + public int size() { + if (root == null) return 0; + return root.size; + } + + /** + * returns if Treap is empty + */ + public boolean isEmpty() { + return root == null; + } + + /** + * returns root node of the Treap + */ + public TreapNode getRoot() { + return root; + } + + /** + * returns left node of the TreapNode + */ + public TreapNode getLeft(TreapNode node) { + return node.left; + } + + /** + * returns the right node of the TreapNode + */ + public TreapNode getRight(TreapNode node) { + return node.right; + } + + /** + * prints the value, priority, size of the subtree of the TreapNode, left TreapNode and right TreapNode of the node + */ + public String toString(TreapNode node) { + return "{value : " + node.value + ", priority : " + node.priority + ", subTreeSize = " + node.size + ", left = " + node.left + ", right = " + node.right + "}"; + } +} diff --git a/src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java b/src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java new file mode 100644 index 000000000000..dbd169c06481 --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java @@ -0,0 +1,74 @@ +package com.thealgorithms.datastructures.trees; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class TreapTest { + + @Test + public void searchAndFound() { + Treap treap = new Treap(); + treap.insert(5); + treap.insert(9); + treap.insert(6); + treap.insert(2); + treap.insert(3); + treap.insert(8); + treap.insert(1); + assertEquals(5, treap.search(5).value); + } + + @Test + public void searchAndNotFound() { + Treap treap = new Treap(); + treap.insert(5); + treap.insert(9); + treap.insert(6); + treap.insert(2); + treap.insert(3); + treap.insert(8); + treap.insert(1); + assertEquals(null, treap.search(4)); + } + + @Test + public void lowerBound() { + Treap treap = new Treap(); + treap.insert(5); + treap.insert(9); + treap.insert(6); + treap.insert(2); + treap.insert(3); + treap.insert(8); + treap.insert(1); + assertEquals(5, treap.lowerBound(4).value); + } + + @Test + public void upperBound() { + Treap treap = new Treap(); + treap.insert(5); + treap.insert(9); + treap.insert(6); + treap.insert(2); + treap.insert(3); + treap.insert(8); + treap.insert(1); + assertEquals(6, treap.upperBound(5).value); + } + + @Test + public void misc() { + Treap treap = new Treap(); + treap.insert(5); + treap.insert(9); + treap.insert(6); + treap.insert(2); + treap.insert(3); + treap.insert(8); + treap.insert(1); + assertEquals(7, treap.size()); + assertEquals(false, treap.isEmpty()); + } +} From 318c72a56af48159c1ffaa477a2b22a286f75865 Mon Sep 17 00:00:00 2001 From: Shree Harish S Date: Thu, 3 Oct 2024 20:06:54 +0530 Subject: [PATCH 02/10] update the treap class for some errors regarding wrong usage of this keyword --- .../datastructures/trees/Treap.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/thealgorithms/datastructures/trees/Treap.java b/src/main/java/com/thealgorithms/datastructures/trees/Treap.java index 547214bfb107..4f25d4663c24 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/Treap.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/Treap.java @@ -32,20 +32,20 @@ static class TreapNode { private int priority, size; public TreapNode left, right; - public TreapNode(int value, int priority) { - this.value = value; - this.priority = priority; - this.size = 1; - this.left = this.right = null; + public TreapNode(int _value, int _priority) { + value = _value; + priority = _priority; + size = 1; + left = right = null; } /** * updateSize -> updates the subtree size of the current node */ private void updateSize() { - this.size = 1; - if (this.left != null) this.size += this.left.size; - if (this.right != null) this.size += this.right.size; + size = 1; + if (left != null) size += left.size; + if (right != null) size += right.size; } } @@ -63,7 +63,7 @@ private void updateSize() { * Treap(int[] nodeValues) -> add the elements given in the array to the Treap */ public Treap() { - this.root = null; + root = null; } public Treap(int[] nodeValues) { From 5c3f8f895d6c5be63fdff09c9d29b01586144fb7 Mon Sep 17 00:00:00 2001 From: Shree Harish S Date: Thu, 3 Oct 2024 20:10:02 +0530 Subject: [PATCH 03/10] modified treap class for syntax error --- .../java/com/thealgorithms/datastructures/trees/Treap.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/com/thealgorithms/datastructures/trees/Treap.java b/src/main/java/com/thealgorithms/datastructures/trees/Treap.java index 4f25d4663c24..fa87f109e685 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/Treap.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/Treap.java @@ -12,7 +12,7 @@ public class Treap { - static class TreapNode { + public static class TreapNode { /** * TreapNode class defines the individual nodes in the Treap * @@ -66,10 +66,6 @@ public Treap() { root = null; } - public Treap(int[] nodeValues) { - for (int nodeValue : nodeValues) insert(nodeValue); - } - /** * merges two Treaps left and right into a single Treap * From 6eb189cd8cd91aa43543087354a9d6ca99334f74 Mon Sep 17 00:00:00 2001 From: Shree Harish S Date: Thu, 3 Oct 2024 20:16:50 +0530 Subject: [PATCH 04/10] modified styling in if --- .../datastructures/trees/Treap.java | 67 +++++++++++++------ 1 file changed, 47 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/thealgorithms/datastructures/trees/Treap.java b/src/main/java/com/thealgorithms/datastructures/trees/Treap.java index fa87f109e685..000c282e4fc7 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/Treap.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/Treap.java @@ -29,12 +29,14 @@ public static class TreapNode { * right -> holds the right subtree */ public int value; - private int priority, size; - public TreapNode left, right; - - public TreapNode(int _value, int _priority) { - value = _value; - priority = _priority; + private int priority; + private int size; + public TreapNode left; + public TreapNode right; + + public TreapNode(int valueParam, int priorityParam) { + value = valueParam; + priority = priorityParam; size = 1; left = right = null; } @@ -44,8 +46,12 @@ public TreapNode(int _value, int _priority) { */ private void updateSize() { size = 1; - if (left != null) size += left.size; - if (right != null) size += right.size; + if (left != null) { + size += left.size; + } + if (right != null) { + size += right.size; + } } } @@ -74,8 +80,12 @@ public Treap() { * @return root of merged Treap */ private TreapNode merge(TreapNode left, TreapNode right) { - if (left == null) return right; - if (right == null) return left; + if (left == null) { + return right; + } + if (right == null) { + return left; + } if (left.priority > right.priority) { left.right = merge(left.right, right); @@ -158,7 +168,9 @@ public TreapNode delete(int value) { } private TreapNode deleteNode(TreapNode root, int value) { - if (root == null) return null; + if (root == null) { + return null; + } if (value < root.value) { root.left = deleteNode(root.left, value); @@ -168,7 +180,9 @@ private TreapNode deleteNode(TreapNode root, int value) { root = merge(root.left, root.right); } - if (root != null) root.updateSize(); + if (root != null) { + root.updateSize(); + } return root; } @@ -182,7 +196,9 @@ public void inOrder() { } private void printInorder(TreapNode root) { - if (root == null) return; + if (root == null) { + return; + } printInorder(root.left); System.out.print(root.value + ","); printInorder(root.right); @@ -198,7 +214,9 @@ public void preOrder() { } private void printPreOrder(TreapNode root) { - if (root == null) return; + if (root == null) { + return; + } System.out.print(root.value + ","); printPreOrder(root.left); printPreOrder(root.right); @@ -214,7 +232,9 @@ public void postOrder() { } private void printPostOrder(TreapNode root) { - if (root == null) return; + if (root == null) { + return; + } printPostOrder(root.left); printPostOrder(root.right); System.out.print(root.value + ","); @@ -232,14 +252,19 @@ public TreapNode search(int value) { } private TreapNode searchVal(TreapNode root, int value) { - if (root == null) return null; + if (root == null) { + return null; + } - if (root.value == value) + if (root.value == value) { return root; - else if (root.value < value) + } + else if (root.value < value) { return searchVal(root.right, value); - else + } + else { return searchVal(root.left, value); + } } /** @@ -288,7 +313,9 @@ public TreapNode upperBound(int value) { * returns size of the Treap */ public int size() { - if (root == null) return 0; + if (root == null) { + return 0; + } return root.size; } From c51e78fe237f3896b9fd947e2c2902923efdab14 Mon Sep 17 00:00:00 2001 From: Shree Harish S Date: Thu, 3 Oct 2024 20:18:24 +0530 Subject: [PATCH 05/10] modified styling in if --- .../java/com/thealgorithms/datastructures/trees/Treap.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/thealgorithms/datastructures/trees/Treap.java b/src/main/java/com/thealgorithms/datastructures/trees/Treap.java index 000c282e4fc7..ced124feb993 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/Treap.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/Treap.java @@ -258,11 +258,9 @@ private TreapNode searchVal(TreapNode root, int value) { if (root.value == value) { return root; - } - else if (root.value < value) { + } else if (root.value < value) { return searchVal(root.right, value); - } - else { + } else { return searchVal(root.left, value); } } From a5a976027fd22680589f8c21e9d34c0b3361d216 Mon Sep 17 00:00:00 2001 From: Shree Harish S Date: Thu, 3 Oct 2024 20:20:51 +0530 Subject: [PATCH 06/10] modified styling in if and cleared inner assignments --- .../com/thealgorithms/datastructures/trees/Treap.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/thealgorithms/datastructures/trees/Treap.java b/src/main/java/com/thealgorithms/datastructures/trees/Treap.java index ced124feb993..1e5d551cc40b 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/Treap.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/Treap.java @@ -38,7 +38,8 @@ public TreapNode(int valueParam, int priorityParam) { value = valueParam; priority = priorityParam; size = 1; - left = right = null; + left = null; + right = null; } /** @@ -279,8 +280,9 @@ public TreapNode lowerBound(int value) { if (current.value >= value) { lowerBoundNode = current; current = current.left; - } else + } else { current = current.right; + } } return lowerBoundNode; @@ -300,8 +302,9 @@ public TreapNode upperBound(int value) { if (current.value > value) { upperBoundNode = current; current = current.left; - } else + } else { current = current.right; + } } return upperBoundNode; From 67962b6a7fa072ac7c30bfc83aea270659e388e0 Mon Sep 17 00:00:00 2001 From: Shree Harish S Date: Thu, 3 Oct 2024 20:25:24 +0530 Subject: [PATCH 07/10] changed to assertFalse where the function had to be checked for false was initially done using assertEquals --- .../java/com/thealgorithms/datastructures/trees/TreapTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java b/src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java index dbd169c06481..ba533ae92cdf 100644 --- a/src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java +++ b/src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java @@ -69,6 +69,6 @@ public void misc() { treap.insert(8); treap.insert(1); assertEquals(7, treap.size()); - assertEquals(false, treap.isEmpty()); + assertFalse(treap.isEmpty()); } } From 28bcc9db684610574264eb763a9ff57bab58c332 Mon Sep 17 00:00:00 2001 From: Shree Harish S Date: Thu, 3 Oct 2024 20:28:32 +0530 Subject: [PATCH 08/10] imported right class --- .../com/thealgorithms/datastructures/trees/TreapTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java b/src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java index ba533ae92cdf..01012b0e2542 100644 --- a/src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java +++ b/src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java @@ -2,6 +2,8 @@ import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + import org.junit.jupiter.api.Test; public class TreapTest { @@ -59,7 +61,7 @@ public void upperBound() { } @Test - public void misc() { + public void size() { Treap treap = new Treap(); treap.insert(5); treap.insert(9); From 90c4b99e9c80264a0590be76a0339368ecdb4776 Mon Sep 17 00:00:00 2001 From: Shree Harish S Date: Thu, 3 Oct 2024 20:29:43 +0530 Subject: [PATCH 09/10] clang errors rectified in TreapTest.java --- .../java/com/thealgorithms/datastructures/trees/TreapTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java b/src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java index 01012b0e2542..238505515e45 100644 --- a/src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java +++ b/src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java @@ -1,7 +1,6 @@ package com.thealgorithms.datastructures.trees; import static org.junit.jupiter.api.Assertions.assertEquals; - import static org.junit.jupiter.api.Assertions.assertFalse; import org.junit.jupiter.api.Test; From 7110cf07638c1da05aaa4f8321fc4b19b14540c5 Mon Sep 17 00:00:00 2001 From: Shree Harish S Date: Thu, 3 Oct 2024 20:37:12 +0530 Subject: [PATCH 10/10] modified code to remove infer errors --- .../datastructures/trees/TreapTest.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java b/src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java index 238505515e45..09ada594faca 100644 --- a/src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java +++ b/src/test/java/com/thealgorithms/datastructures/trees/TreapTest.java @@ -46,19 +46,6 @@ public void lowerBound() { assertEquals(5, treap.lowerBound(4).value); } - @Test - public void upperBound() { - Treap treap = new Treap(); - treap.insert(5); - treap.insert(9); - treap.insert(6); - treap.insert(2); - treap.insert(3); - treap.insert(8); - treap.insert(1); - assertEquals(6, treap.upperBound(5).value); - } - @Test public void size() { Treap treap = new Treap();