Professional Documents
Culture Documents
G ROUP 8 - 22TT1
June 2023
Contents
1 Introduction 2
1.1 Review . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.1 Binary search tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.2 Heap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 Treap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2.1 History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2.2 Definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3 Efficiency of Treap 20
3.1 Time complexity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.2 Space complexity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4 Application 20
4.1 Order statistics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.2 Priority queues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.3 Range queries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.4 Interval trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.5 Dynamic ordering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
5 Quiz 21
6 Programming exercises 22
6.1 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
6.2 Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1
1 Introduction
1.1 Review
Before discussing the main topic, let’s first review BST( Binary search tree) and Heap.
1.1.2 Heap
- Before going to the definition of Heap, we first talk about the complete binary tree. - Definition of
complete binary tree: is a special type of binary tree where all the levels of the tree are filled completely
except the lowest level nodes which are filled from as left as possible.
- Here is some example of the complete binary tree:
- In the following figure, the binary tree is not the complete binary tree because in the last level,
elements are not filled from left to right order.
2
Figure 3: This tree is not a complete tree
- Now, we discuss about Heap. Let’s talk about its definition. Heap is a special Tree-based data
structure in which the tree is a complete binary tree.
- Generally, there are 2 types of Heap:
+ Max-heap: The key present at the root node must be greatest among the keys present at all
of it’s childrens. The same property with all sub-trees in that Binary-tree
+ Min-heap: The key present at the root node must be minimum among the keys present at all
of it’s children. The same property with all sub-trees in that Binary-tree
Figure 4: Heap
1.2 Treap
1.2.1 History
- When talking about BST( Binary search tree), we usually maintain its efficiency in searching and
ordered traversal operations, while, heaps is effient for insertion and deletion.
- The motivation behind constructing a Treap was to create a data structure that maintains the advan-
tages of both BSTs and heaps. The treap was first described by Raimund Seidel and Cecilia R. Aragon
in 1989 and was introduced in a research paper titled ”Randomized Search Trees” published in 1996.
- The name ”treap” is a portmanteau of ”tree” and ”heap,” highlighting the dual nature of the data
structure.
- Researchers have explored different variations and optimizations to improve its performance and
adapt it to specific use cases. The treap has become a valuable tool in algorithm design and data structure
research, offering a balance between the advantages of binary search trees and heaps.
3
(a) Raimund Seidel (b) Cecilia R. Aragon
1.2.2 Definition
- In computer science, Treap is a type of Balanced Binary Search Tree data structure that combines
properties of both a binary search tree (BST) and a Heap. In a treap, each node has two main attributes:
a key and a priority.
- That mean, it maintains two types of ordering: the binary search tree property along the keys and
the heap property along the priorities.
Figure 6: Treap
4
+ A priority value: determines its position in the Heap. The priority values satisfy the heap
property, where the priority value of each node is greater than or equal to the priority values of its
children.
Figure 7: Treap
- Notice that Treap is constructed in such a way that the tree structure is determined by the keys,
while the priorities guide the balancing of the tree.
- Particularly, after inserting a node into the Treap, you may cause an ”imbalance” to the tree. Here
is the example, assume we have a Treap as below:
5
- Now we want to insert a node with a key value is 5 and a priority value is 2. To do that, we will
insert that node as insert a node to the BST tree.
Figure 9: Inserting new node with value 5 and priority 2 to the Treap
- From the above figure, the Treap is become ”imbalance” after insert a new node ( to the left because
the height of the left-subtree is 2 and the height of the right-subtree is 0).
- And here is the power of Treap, after inserting a new node, it will check the priority of the new node
with its parent node if it not satisfy Heap condition, the tree will do the rotation operation recursively
until the tree satisfy the Heap condition.
- The specific idea, algorithm,some operations with Treap step-by-step demo will be introduced in
2.2.
6
2.2 Algorithm
- To begin with, we will discuss about the structure of a single node, then we move to some operations
and so far.
- As mentioned before, each node will have 2 values (key and priority values).
- As a normal node in the BST, it will also have two pointer left and right in which the left pointer
point to the smaller value and the right pointer point to the greater value.
7
- As you can see in the tree the height of the left-subtree is 1 while the right-subtree is 0. Therefore,
the tree is skewed to the left, so we will rotate the tree to the right.
- Notice that keys in both above trees ( after rotation) both satisfy the BST condition ( left node child
smaller and right node child greater than its parent value). BST property is not violated anywhere.
- The following figure will help you have a clear view of Left and Right rotation. If you rotate the
tree to the left and then rotate it to the right, the tree will return to its initial shape.
8
Figure 15: Left and Right rotaion
- With the previous idea and diagram, we have two functions called ’rotateRight’ and ’rotateLeft’ as
below:
9
2.2.2 Create a new Treap Node
- Create a new Treap Node remain the same as create a normal Node, except one thing that, we need
to assign a priority value to the node.
- Remember that the priority value should be assigned randomly or according to a specific criterion
to maintain the desired balance and heap property of the Treap.
1. HeapifyUp
- Remember in Figure 9, We have a Treap with a new node with a key value is 5 and a priority value
is 2.
10
Figure 19: Treap after insert node (5,2)
- As you can see, node (5,2) ( with key value 5 and priority value 2) has its parent (6,7). This does
not satisfy the Heap condition of the tree, therefore we will use tree rotation to change the shape of the
tree.
- Have a look at node (6,7) its left node does not satisfy the Heap condition, so we will change the
position of node (6,7) and its child node (5,2). To do that, we will use Right rotation to node (6,7)
11
- Then the process continues, node (5,2) now has its parent is node (3,4), therefore we will change
the position of node (3,4) and node (5,2) ( because the priority value of node (5,2) is smaller than node
(3,4) ). Notice that, node (5,2) is the right child node, hence, we use Left rotation to node (3,4)
- Notice that, after these two operations, the tree with root (5,2) now satisfies both BST and Heap
condition ( the left smaller, the right greater and the parent node priority value is greater than its child
priority value)
- ’heapifyUp’ actually is the combination of two functions ’rotateLeft’ and ’rotaterRight’. The
’heapifyUp’ will check the given root in the parameter and then change the shape of the tree of that
root.
2. Insertion
- From the introduction of ’heapifyUp’, you may imagine how the Heap condition is conserved as
well as how to insert a new node to a Treap.
- To insert a new node into a Treap, we will have two steps:
+ Insert a new node as well as insert a node to the BST.
+ Using ’heapifyUp’ to change the shape of the tree ( if necessary) to conserve Heap ability
of the tree ( this process will be done recursively by the following figure)
12
Figure 23: insert new node to a Treap and check the Heap condition
- After inserting a new node into the Treap, ’heapifyUp’ will be called to check the condition of the
current node with its subtree and then rotate that tree if it is necessary to protect the Heap condition of
the tree.
13
Figure 24: ’insert’ function
- The function will first insert a new node to the Treap as with BST, then, it will check on the path
from itself to the root, if the subtree does not satisfy the Heap condition, the ’heapifyUp’ function will
change its shape. The process continues until it reaches the root node.
14
Figure 26: Delete node with 1 child
- If node (9,5) in the previous example only has left child, the process remains the same.
- Now, we consider a situation where the target has two children.
15
- To delete a node with two children, we first check the priority value of its left and right child,
assuming that, the right node has smaller priority value, then we will rotate left for the target. This is
because we want the target to have one child (leading to the situation we have considered before) and
also conserve the Heap condition of the Treap.
- After rotating the target, you may find that the target has violated the Heap condition of the tree.
But don’t worry, because in the next function call, it will be deleted and the Heap condition will remain
satisfied for the new Treap.
- After deleting a node, not only the BST property of the Treap but also the Heap property is con-
served.
16
Figure 29: ’delete’ function
17
Figure 30: ’search’ function
18
Figure 32: ’inorder’ function
19
3 Efficiency of Treap
- To evaluation the efficiency of the Treap, we will talk about two section: Time complexity and
Space complexity.
4 Application
- As mentioned before,Treap (Tree + Heap) is a data structure that combines the properties of a
binary search tree and a binary heap. It provides efficient operations for both searching and inserting
elements, making it useful in various applications. Here are a few common applications of Treap
20
4.4 Interval trees
- Treap can be used to implement interval trees efficiently. Interval trees store intervals of the form
[start, end] and support operations like finding all intervals overlapping a given interval or finding the
interval containing a specific point.
- Conclusion, he flexibility and efficiency of Treap make it a valuable data structure in various
domains, including algorithms, data storage, and computational geometry.
5 Quiz
1. Which is the tree type of the Treap (choose the most correct one):
a. Binary Tree
b. Binary Search Tree
c. Self-balancing binary search tree
d. Tree
3.What is the time complexity of insert and delete operation in a treap on average?
a. O(N)
b. O(log N)
c. O(N log N)
d. O(N2 )
5. What is the condition for priority of a node in a treap besed on Min Heap?
a. a node’s priority should be greater than its parent
b. a node’s priority should be at least as large as its parent
c. the priority is randomly assigned and can have any value
d. a node’s priority is always given in decreasing order
6. Several other operations like union set difference and intersection can be done in treaps.
a. True
b. False
7. Which node has the lowest priority in a treap based on Min Heap?
a. root node
21
b. leaf node
c. null node
d. centre node
6 Programming exercises
6.1 Exercises
Problem 1. Building a Treap by hand: To better understand how Treaps work, it can be useful to
manually build a small Treap by hand, using a pen and paper. The task is to choose a set of keys and
priorities, and then use the Treap operations of insert and rotate to build a valid Treap.
- Insert:
• 95 38
• 39 6
• 6 43
• 26 82
• 25 55
• 54 25
• 47 48
• 12 71
• 92 100
Where the first number in each row is the value and the second one is the priority.
Problem 2. Using the above processes and thoughts, implement a full-fledge Treap that can do the
following operations: insert, delete and search.
Problem 3. Using a treap as a binary search tree. Treap is also used as a self-balancing binary
search tree to minimize the search operation time. Using the above implementation of Treap to solve the
following problem:
https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tre
e/description/
Problem 4. Using a treap as a set like std:set in C++.Treap is also used as a set to minimize the
overall complexity when doing insertions,deletions and searching as well as lower bound and upper
bound. Using the above implementation of Treap or the modified version of it to solve the following
problem:
https://codeforces.com/contest/1041/problem/C
6.2 Solution
Problem 1.
- The following diagram will discuss step by step the process of inserting node to the Treap.
Problem 2.
a. Insertion
• To insert an element into a Treap based on a min-heap, we first create a new node with the key
and priority values of the element. We then traverse the tree, starting at the root, and compare the key of
the new node with the keys of the nodes we encounter. If the new node’s key is less than the key of the
current node, we move to the left subtree; if it is greater, we move to the right subtree. We continue this
process until we reach a null node, at which point we insert the new node into the tree.
• Once the new node is inserted, we may need to perform a rotation to maintain the Treap property.
A rotation is a simple operation that changes the structure of the tree while preserving the ordering of
22
Figure 35: Insert to the Treap
the nodes. There are two types of rotations: left and right. In a left rotation, we move the parent node
down to the left, and move its right child up to take its place. In the right rotation, we do the opposite.
• The rotation is performed if the priority of the new node is less than the priority of its parent. In
this case, we perform a rotation such that the new node becomes the parent of the previous parent node,
and the previous parent node becomes a child of the new node.
23
b Deletion
• To delete an element from a Treap based on a min-heap, we first find the node with the correspond-
ing key. If the node is not found, we simply return. Otherwise, we remove the node from the tree by
either replacing it with its left child, its right child, or the node that has the next lowest priority value.
• To replace the node with its left child, we simply move the left child up to take the place of the
node. If the node has no left child, we replace it with its right child. If the node has both left and right
children, we replace it with the node that has the next lowest priority value. This is done by finding the
node with the next lowest priority value in the right subtree, replacing the node to be deleted with this
node, and then deleting the node with the next lowest priority value.
• Once the node is deleted, we may need to perform a rotation to maintain the Treap property. If the
node that was deleted was a leaf node, we simply remove it from the tree and return. If the node had one
child, we replace it with its child. If the node had two children, we find the child with the lowest priority
and perform a rotation to move it up to take the place of the deleted node.
c. Search
• To search for an element in a Treap based on a min-heap, we start at the root and compare the key
of the node with the key we are searching for. If the key of the node is equal to the key we are searching
for, we return the node. If the key of the node is less than the key we are searching for, we move to the
right subtree; if it is greater, we move to the left subtree. We continue this process until we either find
the node or reach a null node.
Problem 3.
• Problem Description
⋄ The problem of finding the lowest common ancestor of two nodes in a Binary Search Tree (BST)
requires us to find the node that is the parent of the given two nodes and is also the lowest in the tree. In
other words, it is the deepest node that has both the given nodes as descendants.
• Ideas:
⋄ The property of a BST is that all nodes in the left subtree of a node are less than the node, and all
nodes in the right subtree are greater than the node.
⋄ We can start by comparing the values of the two nodes with the value of the current node. If both
the nodes are greater than the current node, we can recursively search in the right subtree of the current
node. If both the nodes are less than the current node, we can recursively search in the left subtree of the
current node.
⋄ If one node is less than the current node and the other node is greater than the current node, then
the current node is the lowest common ancestor of the two nodes.
• Algorithm:
⋄ The algorithm for finding the lowest common ancestor of two nodes in a Binary Search Tree can
be written in a recursive manner. We can start by checking if the root node is null or if both the nodes
are null, in which case we can return null as there is no common ancestor.
⋄ If one of the nodes is null, we can return the other node as the common ancestor as it is the only
node that can be the ancestor of the non-null node.
⋄ If both the nodes are present, we can compare their values with the value of the current node. If
both the nodes are less than the current node, we can recursively search in the left subtree of the current
node. If both the nodes are greater than the current node, we can recursively search in the right subtree
of the current node.
⋄ If one node is less than the current node and the other node is greater than the current node, then
the current node is the lowest common ancestor of the two nodes, and we can return it.
• The Treap part:
⋄ Now, what about using Treap to solve the problem.The steps are pretty much exactly similar to
the one we have mentioned above. Remember, Treap is basically a Binary Search Tree with the height
about O(logN), so while solving the above problem with normal BST costs O(h) time (h is the height
24
of the tree, possibly O(N) in the worst case), solving with Treap makes the time becomes O(logN)) in
average, which is a huge improvement.
Problem 4.
• Problem Description:
⋄ The problem requires us to determine the minimum number of days needed to complete a list of
tasks, where each task has a specified duration and a deadline.
• Ideas:
⋄ We can approach this problem by using a greedy algorithm that schedules the tasks in the order of
their deadlines and tries to complete as many tasks as possible in a single day.
• Algorithm:
⋄ To implement this algorithm, we can first create a set of pairs that represent the duration and the
index of each task, sorted by their deadlines. We can use the duration to determine the time required to
complete each task, and the index to keep track of which task we are currently working on.
⋄ We can then iterate over the set while it contains elements, determining the breaks that should be
taken in a single day. For each day, we will start with the first task that has a deadline equal to the time
at the beginning of the set (let this time be denoted as x). We will take a break after completing each
task, and we must ensure that the next break is taken after at least d minutes.
⋄ To find the next task that should be completed, we can use the lower-bound function to find the
first pair in the set where the first element (i.e., the duration of the task) is not less than x+d+1. This will
give us the task with the earliest deadline that can be completed after the required break. We can then
repeat this process to find the next task that should be completed until we have completed all tasks for
the day.
⋄ To keep track of the answer days for each task, we can use the second element of the pairs, which
represents the index of the task in the input data. We can easily remember the answer days for each task
by using a separate array that maps the index to the day on which the task was completed.
⋄ Finally, we must ensure that we remove all considered pairs from the set to avoid considering them
again in future iterations. If we cannot find a pair that satisfies the requirements for a particular day, we
must move on to the next day and repeat the process until all tasks have been completed.
• The Treap part:
⋄ For this particular problem, you cannot use the standard std::set or the likes to solve ; you have to
solve using the Treap class you have implemented.You may have to modify the class a bit to fit the task
description (change node data from int to std::pair, implement lower-bound and compare methods for
std::pair, etc)
25
References
[1] https://en.wikipedia.org/wiki/Binary_search_tree
[2] https://www.geeksforgeeks.org/heap-data-structure/
[3] https://www.geeksforgeeks.org/complete-binary-tree/
[4] https://www.geeksforgeeks.org/treap-a-randomized-binary-search-tree/
[5] https://en.wikipedia.org/wiki/Treap
[6] https://www.javatpoint.com/treap-data-structure
[7] https://codelearn.io/learning/data-structure-and-algorithms
[8] https://vietcodes.github.io/algo/treap
[9] https://www.geeksforgeeks.org/tree-traversals-inorder-preorder-and-postord
er/
[10] https://www.geeksforgeeks.org/implementation-of-search-insert-and-delete-i
n-treap/
[11] https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-t
ree/solutions/
[12] https://codeforces.com/blog/entry/61876
[13] https://cp-algorithms.com/data_structures/treap.html
[14] https://alexdremov.me/treap-algorithm-explained/
[15] https://usaco.guide/adv/treaps?lang=cpp
26