Treap data structure is a Cartesian tree in which each key is given a (randomly chosen) numeric priority described by Raimund Seidel and Cecilia R. Aragon in 1989.
In this tutorial, we will learn about the Treap data structure and how to implement a Treap in javascript.
What is Treap data structure?.
A Treap data structure is a Balanced Binary Search Tree, which combines the best of both the heaps and binary search trees, but not guaranteed to have height as O(Log n).
It store two values.
1. A key (Ordered according to the BST property).
2. And a randomly chosen numeric priority (A random value ordered according to max-heap property).
The structure of the tree is determined by the requirement that it be heap-ordered: that is, the priority number for any non-leaf node must be greater than or equal to the priority of its children.
It is often considered as a good platform to build the randomized binary search tree.

List of operations performed on treap.
- insertNode(key):- Adds a new node with random priority.
- deleteNode(key):- Removes a node with the given key.
- searchNode(key):- Returns true if key is present in the treap, false otherwise.
- printTreap:- Prints the node in the BST order.
Implementing treap data structure in Javascript.
We will need to helper functions in-order to implement a treap rotateLeft, rotateRight which reverses the parent-child relation.
Base structure
//Generates a random number
const getRandom = (max, min = 1) => {
return Math.floor((Math.random() * (max - min + 1)) + min);
}
const Treap = function() {
//Node with priority
const Node = function(data){
this.data = data;
this.priority = getRandom(100);
this.left = this.right = null;
}
//To store the root
let root = null;
const rotateLeft = function(root) {
const R = root.right;
const X = root.right.left;
// rotate
R.left = root;
root.right = X;
// set new root
return R;
}
const rotateRight = function(root) {
const L = root.left;
const Y = root.left.right;
// rotate
L.right = root;
root.left = Y;
// set new root
return L;
}
//Other methods will go here
}
Insert operation on the treap.
To insert a key in the treap, create a new node with random priority and add it at the leaf position using the BST property to determine its initial position and then if the new node is not the root and has greater priority value than the parent then perform the tree rotation, to reverse its position with the parent.

// Recursive function to insert a given key with a priority into Treap
this.insertNode = function(data) {
const insertNodeHelper = (root, data) => {
// base case
if (root === null) {
return new Node(data);
}
// if data is less than the root node, insert in the left subtree
// else insert in the right subtree
if (data < root.data) {
root.left = insertNodeHelper(root.left, data);
// rotate right if heap property is violated
if (root.left != null && root.left.priority > root.priority) {
root = rotateRight(root);
}
}
else {
root.right = insertNodeHelper(root.right, data);
// rotate left if heap property is violated
if (root.right != null && root.right.priority > root.priority) {
root = rotateLeft(root);
}
}
return root;
}
root = insertNodeHelper(root, data);
}
Delete operation on treap.
To remove a node with given key from the treap we have to check for the following conditions.
- If the node is the leaf then remove it.
- If the node has only single child then remove the node and replace its position with its child.
- In case node has two child, swap its position in the tree with its immediate successor in the sorted order, resulting in one of the previous cases. Swapping may disrupt the heap-order priority, so we need to perform additional rotations to restore the property.

// Recursive function to delete a key from the given Treap
this.deleteNode = function(key) {
const deleteNodeHelper = (root, key) => {
// base case: key not found in tree
if (root === null) {
return null;
}
// if key is less than the root node, recur for left subtree
if (key < root.data) {
root.left = deleteNodeHelper(root.left, key);
}
// if key is more than the root node, recur for right subtree
else if (key > root.data) {
root.right = deleteNodeHelper(root.right, key);
}
// if key found
else
{
// Case 1: node to be deleted has no children (it is a leaf node)
if (root.left == null && root.right == null)
{
// deallocate the memory and update root to null
root = null;
}
// Case 2: node to be deleted has two children
else if (root.left != null && root.right != null)
{
// if left child has less priority than right child
if (root.left.priority < root.right.priority)
{
// call rotateLeft on root
root = rotateLeft(root);
// recursively delete the left child
root.left = deleteNodeHelper(root.left, key);
}
else
{
// call rotateRight on root
root = rotateRight(root);
// recursively delete the right child
root.right = deleteNodeHelper(root.right, key);
}
}
// Case 3: node to be deleted has only one child
else
{
// find child node
const child = (root.left != null) ? root.left: root.right;
root = child;
}
}
return root;
}
root = deleteNodeHelper(root, key);
}
Search operation in treap
To search a key, we can use the standard search operation of BST, ignoring the priority.
// Recursive function to search for a key in the given Treap
this.searchNode = function(key) {
const searchNodeHelper = (root, key) => {
// if key is not present in the key
if (root === null) {
return false;
}
// if key is found
if (root.data == key) {
return true;
}
// if key is less than the root node, search in the left subtree
if (key < root.data) {
return searchNodeHelper(root.left, key);
}
// else search in the right subtree
return searchNodeHelper(root.right, key);
}
return searchNodeHelper(root, key);
}
Print operation on treap.
Print the nodes in the BST order.
this.printTreap = function() {
const printTreapHealper = (root) => {
// Base case
if (root === null) {
return;
}
// print right child first
printTreapHealper(root.right);
console.log(root.data + "(" + root.priority + ")");
// print left child
printTreapHealper(root.left);
}
printTreapHealper(root);
}
}
Complete code of Treap data structure in Javascript.
const getRandom = (max, min = 1) => {
return Math.floor((Math.random() * (max - min + 1)) + min);
}
const Treap = function() {
const Node = function(data){
this.data = data;
this.priority = getRandom(100);
this.left = this.right = null;
}
let root = null;
const rotateLeft = function(root) {
const R = root.right;
const X = root.right.left;
// rotate
R.left = root;
root.right = X;
// set new root
return R;
}
const rotateRight = function(root) {
const L = root.left;
const Y = root.left.right;
// rotate
L.right = root;
root.left = Y;
// set new root
return L;
}
// Recursive function to insert a given key with a priority into Treap
this.insertNode = function(data) {
const insertNodeHelper = (root, data) => {
// base case
if (root === null) {
return new Node(data);
}
// if data is less than the root node, insert in the left subtree
// else insert in the right subtree
if (data < root.data) {
root.left = insertNodeHelper(root.left, data);
// rotate right if heap property is violated
if (root.left != null && root.left.priority > root.priority) {
root = rotateRight(root);
}
}
else {
root.right = insertNodeHelper(root.right, data);
// rotate left if heap property is violated
if (root.right != null && root.right.priority > root.priority) {
root = rotateLeft(root);
}
}
return root;
}
root = insertNodeHelper(root, data);
}
// Recursive function to search for a key in the given Treap
this.searchNode = function(key) {
const searchNodeHelper = (root, key) => {
// if key is not present in the key
if (root === null) {
return false;
}
// if key is found
if (root.data == key) {
return true;
}
// if key is less than the root node, search in the left subtree
if (key < root.data) {
return searchNodeHelper(root.left, key);
}
// else search in the right subtree
return searchNodeHelper(root.right, key);
}
return searchNodeHelper(root, key);
}
// Recursive function to delete a key from the given Treap
this.deleteNode = function(key) {
const deleteNodeHelper = (root, key) => {
// base case: key not found in tree
if (root === null) {
return null;
}
// if key is less than the root node, recur for left subtree
if (key < root.data) {
root.left = deleteNodeHelper(root.left, key);
}
// if key is more than the root node, recur for right subtree
else if (key > root.data) {
root.right = deleteNodeHelper(root.right, key);
}
// if key found
else
{
// Case 1: node to be deleted has no children (it is a leaf node)
if (root.left == null && root.right == null)
{
// deallocate the memory and update root to null
root = null;
}
// Case 2: node to be deleted has two children
else if (root.left != null && root.right != null)
{
// if left child has less priority than right child
if (root.left.priority < root.right.priority)
{
// call rotateLeft on root
root = rotateLeft(root);
// recursively delete the left child
root.left = deleteNodeHelper(root.left, key);
}
else
{
// call rotateRight on root
root = rotateRight(root);
// recursively delete the right child
root.right = deleteNodeHelper(root.right, key);
}
}
// Case 3: node to be deleted has only one child
else
{
// find child node
const child = (root.left != null) ? root.left: root.right;
root = child;
}
}
return root;
}
root = deleteNodeHelper(root, key);
}
// Utility function to print two-dimensional view of a Treap using
// reverse inorder traversal
this.printTreap = function() {
const printTreapHealper = (root) => {
// Base case
if (root === null) {
return;
}
// print right child first
printTreapHealper(root.right);
console.log(root.data + "(" + root.priority + ")");
// print left child
printTreapHealper(root.left);
}
printTreapHealper(root);
}
}
Input:
const arr = [5, 2, 1, 4, 9, 8, 10];
const treap = new Treap();
for(let val of arr){
root = treap.insertNode(val);
}
treap.printTreap();
root = treap.deleteNode(1);
console.log(" ");
console.log(treap.searchNode(8));
console.log(" ");
treap.printTreap();
Output:
"10(9)"
"9(71)"
"8(5)"
"5(21)"
"4(62)"
"2(8)"
"1(25)"
" "
true
" "
"10(9)"
"9(71)"
"8(5)"
"5(21)"
"4(62)"
"2(8)"
Time complexity of treap data structure
| # | Access | Search | Insert | Delete |
|---|---|---|---|---|
| Average | ΘLog(N) | ΘLog(N) | ΘLog(N) | ΘLog(N) |
| Worst | OLog(N) | OLog(N) | OLog(N) | OLog(N) |
Space complexity
| # | Space |
|---|---|
| Worst | N |