Programming
Lakehead University TreapADT and SplitTree Method Java Programming Project

Lakehead University

Question Description

I’m stuck on a Java question and need an explanation.

First: Implement the class TreapADT including an search, insert, and delete methods.

Then split the tree by adding a SplitTree method.

? The tree splitting problem is this: 

? Given a tree and a key value K not in the tree, create two trees: One with keys less than K, and one with keys greater than K

? This is easy to solve with a treap, once the insert operation has been implemented:

? Insert (K, INFINITY) in the treap 

? Since this has a higher priority than any node in the heap, it will become the root of the treap after insertion 

? Because of the BST ordering property, the left subtree of the root will be a treap with keys less than K, and the right subtree of the root will be a treap with keys greater than K. These subtrees then are the desired result of the split 

? Since insert can be done in time O(H) where H is the height of the treap, splitting can also be done in time O(H)

Unformatted Attachment Preview

Treap (A Randomized Binary Search Tree) Like Red-Black and AVL Trees, Treap is a Balanced Binary Search Tree, but not guaranteed to have height as O(Log n). The idea is to use Randomization and Binary Heap property to maintain balance with high probability. The expected time complexity of search, insert and delete is O(Log n). Every node of Treap maintains two values. 1) Key Follows standard BST ordering (left is smaller, and right is greater) 2) Priority Randomly assigned value that follows Max-Heap property. Basic Operation on Treap: Like other self-balancing Binary Search Trees, Treap uses rotations to maintain Max-Heap property during insertion and deletion. T1, T2 and T3 are subtrees of the tree rooted with y (on left side) or x (on right side) y x / \ x T3 / \ T1 Right Rotation / – – – – – – – > T1 < - - - - - - T2 Left Rotation \ y / \ T2 T3 Keys in both of the above trees follow the following order keys(T1) < key(x) < keys(T2) < key(y) < keys(T3) So BST property is not violated anywhere. search(x) Perform standard BST Search to find x. Insert(x): 1) Create new node with key equals to x and value equals to a random value. 2) Perform standard BST insert. 3) Use rotations to make sure that inserted node's priority follows max heap property. Delete(x): 1) If node to be deleted is a leaf, delete it. 2) Else replace node's priority with minus infinite ( -INF ), and do appropriate rotations to bring the node down to a leaf. Refer Implementation of Treap Search, Insert and Delete for more details. In this post, implementations of search, insert and delete are discussed. Search: Same as standard BST search. Priority is not considered for search. // C function to search a given key in a given BST TreapNode* search(TreapNode* root, int key) { // Base Cases: root is null or key is present at root if (root == NULL || root->key == key) return root; // Key is greater than root's key if (root->key < key) return search(root->right, key); // Key is smaller than root's key return search(root->left, key); } Insert 1) Create new node with key equals to x and value equals to a random value. 2) Perform standard BST insert. 3) A newly inserted node gets a random priority, so Max-Heap property may be violated. Use rotations to make sure that inserted node’s priority follows max heap property. During insertion, we recursively traverse all ancestors of the inserted node. a) If new node is inserted in left subtree and root of left subtree has higher priority, perform right rotation. b) If new node is inserted in right subtree and root of right subtree has higher priority, perform left rotation. /* Recursive implementation of insertion in Treap */ TreapNode* insert(TreapNode* root, int key) { // If root is NULL, create a new node and return it if (!root) return newNode(key); // If key is smaller than root if (key <= root->key) { // Insert in left subtree root->left = insert(root->left, key); // Fix Heap property if it is violated if (root->left->priority > root->priority) root = rightRotate(root); } else // If key is greater { // Insert in right subtree root->right = insert(root->right, key); // Fix Heap property if it is violated if (root->right->priority > root->priority) root = leftRotate(root); } return root; } Delete: The delete implementation here is slightly different from the steps discussed in first section above 1) If node is a leaf, delete it. 2) If node has one child NULL and other as non-NULL, replace node with the non-empty child. 3) If node has both children as non-NULL, find max of left and right children. ….a) If priority of right child is greater, perform left rotation at node ….b) If priority of left child is greater, perform right rotation at node. The idea of step 3 is to move the node to down so that we end up with either case 1 or case 2. /* Recursive implementation of Delete() */ TreapNode* deleteNode(TreapNode* root, int key) { // Base case if (root == NULL) return root; // IF KEYS IS NOT AT ROOT if (key < root->key) root->left = deleteNode(root->left, key); else if (key > root->key) root->right = deleteNode(root->right, key); // IF KEY IS AT ROOT // If left is NULL else if (root->left == NULL) { TreapNode *temp = root->right; delete(root); root = temp; // Make right child as root } // If Right is NULL else if (root->right == NULL) { TreapNode *temp = root->left; delete(root); root = temp; // Make left child as root } // If ksy is at root and both left and right are not NULL else if (root->left->priority < root->right->priority) { root = leftRotate(root); root->left = deleteNode(root->left, key); } else { root = rightRotate(root); root->right = deleteNode(root->right, key); } return root; } A Compete Program to Demonstrate All Operations // C++ program to demosntrate search, insert and delete in Treap #include using namespace std; // A Treap Node struct TreapNode { int key, priority; TreapNode *left, *right; }; /* T1, T2 and T3 are subtrees of the tree rooted with y (on left side) or x (on right side) y x / \ Right Rotation / \ x T3 – – – – – – – > T1 y / \ < - - - - - - / \ T1 T2 Left Rotation T2 T3 */ // A utility function to right rotate subtree rooted with y // See the diagram given above. TreapNode *rightRotate(TreapNode *y) { TreapNode *x = y->left, *T2 = x->right; // Perform rotation x->right = y; y->left = T2; // Return new root return x; } // A utility function to left rotate subtree rooted with x // See the diagram given above. TreapNode *leftRotate(TreapNode *x) { TreapNode *y = x->right, *T2 = y->left; // Perform rotation y->left = x; x->right = T2; // Return new root return y; } /* Utility function to add a new key */ TreapNode* newNode(int key) { TreapNode* temp = new TreapNode; temp->key = key; temp->priority = rand()%100; temp->left = temp->right = NULL; return temp; } // C function to search a given key in a given BST TreapNode* search(TreapNode* root, int key) { // Base Cases: root is null or key is present at root if (root == NULL || root->key == key) return root; // Key is greater than root's key if (root->key < key) return search(root->right, key); // Key is smaller than root's key return search(root->left, key); } /* Recursive implementation of insertion in Treap */ TreapNode* insert(TreapNode* root, int key) { // If root is NULL, create a new node and return it if (!root) return newNode(key); // If key is smaller than root if (key <= root->key) { // Insert in left subtree root->left = insert(root->left, key); // Fix Heap property if it is violated if (root->left->priority > root->priority) root = rightRotate(root); } else // If key is greater { // Insert in right subtree root->right = insert(root->right, key); // Fix Heap property if it is violated if (root->right->priority > root->priority) root = leftRotate(root); } return root; } /* Recursive implementation of Delete() */ TreapNode* deleteNode(TreapNode* root, int key) { if (root == NULL) return root; if (key < root->key) root->left = deleteNode(root->left, key); else if (key > root->key) root->right = deleteNode(root->right, key); // IF KEY IS AT ROOT // If left is NULL else if (root->left == NULL) { TreapNode *temp = root->right; delete(root); root = temp; // Make right child as root } // If Right is NULL else if (root->right == NULL) { TreapNode *temp = root->left; delete(root); root = temp; // Make left child as root } // If ksy is at root and both left and right are not NULL else if (root->left->priority < root->right->priority) { root = leftRotate(root); root->left = deleteNode(root->left, key); } else { root = rightRotate(root); root->right = deleteNode(root->right, key); } return root; } // A utility function to print tree void inorder(TreapNode* root) { if (root) { inorder(root->left); cout << "key: "<< root->key << " | priority: %d " << root->priority; if (root->left) cout << " | left child: " << root->left->key; if (root->right) cout << " | right child: " << root->right->key; cout << endl; inorder(root->right); } } // Driver Program to test above functions int main() { srand(time(NULL)); struct root = root = root = root = root = root = root = TreapNode *root = NULL; insert(root, 50); insert(root, 30); insert(root, 20); insert(root, 40); insert(root, 70); insert(root, 60); insert(root, 80); cout << "Inorder traversal of the given tree \n"; inorder(root); cout << "\nDelete 20\n"; root = deleteNode(root, 20); cout << "Inorder traversal of the modified tree \n"; inorder(root); cout << "\nDelete 30\n"; root = deleteNode(root, 30); cout << "Inorder traversal of the modified tree \n"; inorder(root); cout << "\nDelete 50\n"; root = deleteNode(root, 50); cout << "Inorder traversal of the modified tree \n"; inorder(root); TreapNode *res = search(root, 50); (res == NULL)? cout << "\n50 Not Found ": cout << "\n50 found"; return 0; } Output: Inorder traversal of the given tree key: 20 | priority: %d 92 | right child: 50 key: 30 | priority: %d 48 | right child: 40 key: 40 | priority: %d 21 key: 50 | priority: %d 73 | left child: 30 | right child: 60 key: 60 | priority: %d 55 | right child: 70 key: 70 | priority: %d 50 | right child: 80 key: 80 | priority: %d 44 Delete 20 Inorder traversal of the modified tree key: 30 | priority: %d 48 | right child: 40 key: 40 | priority: %d 21 key: 50 | priority: %d 73 | left child: 30 | right child: 60 key: 60 | priority: %d 55 | right child: 70 key: 70 | priority: %d 50 | right child: 80 key: 80 | priority: %d 44 Delete 30 Inorder traversal of the modified tree key: 40 | priority: %d 21 key: 50 | priority: %d 73 | left child: 40 | right child: 60 key: 60 | priority: %d 55 | right child: 70 key: 70 | priority: %d 50 | right child: 80 key: 80 | priority: %d 44 Delete 50 Inorder traversal of the modified tree key: 40 | priority: %d 21 key: 60 | priority: %d 55 | left child: 40 | right child: 70 key: 70 | priority: %d 50 | right child: 80 key: 80 | priority: %d 44 50 Not Found Explanation of above output: Every node is written as key(priority) The above code constructs below tree 20(92) \ 50(73) / \ 30(48) 60(55) \ \ 40(21) 70(50) \ 80(44) After deleteNode(20) 50(73) / \ 30(48) 60(55) \ \ 40(21) 70(50) \ 80(44) After deleteNode(30) 50(73) / \ 40(21) 60(55) \ 70(50) \ 80(44) After deleteNode(50) 60(55) / \ 40(21) 70(50) \ 80(44) Thanks to Jai Goyal for providing initial implementation. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. ...
Purchase answer to see full attachment
Student has agreed that all tutoring, explanations, and answers provided by the tutor will be used to help in the learning process and in accordance with Studypool's honor code & terms of service.

Final Answer

Here's the complete solution in Java.Note that I've referred ...

wolfram777 (1654)
Carnegie Mellon University

Anonymous
Thanks for the help.

Anonymous
Outstanding. Studypool always delivers quality work.

Anonymous
Tutor was very helpful and took the time to explain concepts to me. Very responsive, managed to get replies within the hour.

Studypool
4.7
Trustpilot
4.5
Sitejabber
4.4