Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
C++ Program to Implement Splay Tree
Splay Tree
Splay tree is a self-balanced binary searched tree. The idea of implementing the splay tree is to bring the most recently inserted element to the root of the tree by performing a sequence of tree rotations, called splaying.
Following are the basic operation on AVL:
- Insertion
- Searching
- Deletion
- Rotation: There are two types of rotation in splay tree (zig rotation and zag rotation).
Let's see the code snippet of the above operation:
Insertion
Efficiently inserts a new key into the splay tree while keeping frequently used nodes close to the root. The tree self-adjusts using rotations to optimize future access time.
s * Insert(int key, s * root) {
s * p_node = New_Node(key);
if (!root) return p_node;
root = Splay(key, root);
if (key < root -> k) {
p_node -> lch = root -> lch;
p_node -> rch = root;
root -> lch = NULL;
return p_node;
} else if (key > root -> k) {
p_node -> rch = root -> rch;
p_node -> lch = root;
root -> rch = NULL;
return p_node;
} else {
delete p_node;
return root;
}
}
Searching
Searches for a key and brings it to the root if found using splay operations. This reduces access time for frequently searched elements.
s* Search(int key, s* root) {
return Splay(key, root);
}
Deletion
Deletes a node while maintaining tree balance via rotations and splaying. Ensures the splay tree remains optimized after removal of a key.
s* Delete(int key, s* root) {
if (!root) return NULL;
root = Splay(key, root);
if (key != root->k) return root;
s* temp;
if (!root->lch) {
temp = root;
root = root->rch;
} else {
temp = root;
root = Splay(key, root->lch);
root->rch = temp->rch;
}
delete temp;
return root;
}
Rotation
Rotations like right and left (Zig-Zig, Zag-Zag) bring nodes closer to the root. These are key to maintaining splay tree efficiency after every operation.
Right Rotation (Zig-Zig/Zig)
It is used when the key in the left subtree of the left child.
s* RR_Rotate(s* k2) {
s* k1 = k2->lch;
k2->lch = k1->rch;
k1->rch = k2;
return k1;
}
Left Rotation (Zag-Zag/Zag)
It is used when the key in the right subtree of the left child.
s* RR_Rotate(s* k2) {
s* k1 = k2->lch;
k2->lch = k1->rch;
k1->rch = k2;
return k1;
}
Implementation of Splay Tree in C++
Following is a C++ example of the implementation of the splay tree:
#include <iostream>
#include <cstdlib>
using namespace std;
struct s {
int k;
s * lch;
s * rch;
};
class SplayTree {
public: s * RR_Rotate(s * k2) {
s * k1 = k2 -> lch;
k2 -> lch = k1 -> rch;
k1 -> rch = k2;
return k1;
}
s * LL_Rotate(s * k2) {
s * k1 = k2 -> rch;
k2 -> rch = k1 -> lch;
k1 -> lch = k2;
return k1;
}
s * Splay(int key, s * root) {
if (!root) return NULL;
s header;
header.lch = header.rch = NULL;
s * LeftTreeMax = & header;
s * RightTreeMin = & header;
while (true) {
if (key < root -> k) {
if (!root -> lch) break;
if (key < root -> lch -> k) {
root = RR_Rotate(root);
if (!root -> lch) break;
}
RightTreeMin -> lch = root;
RightTreeMin = RightTreeMin -> lch;
root = root -> lch;
RightTreeMin -> lch = NULL;
} else if (key > root -> k) {
if (!root -> rch) break;
if (key > root -> rch -> k) {
root = LL_Rotate(root);
if (!root -> rch) break;
}
LeftTreeMax -> rch = root;
LeftTreeMax = LeftTreeMax -> rch;
root = root -> rch;
LeftTreeMax -> rch = NULL;
} else break;
}
LeftTreeMax -> rch = root -> lch;
RightTreeMin -> lch = root -> rch;
root -> lch = header.rch;
root -> rch = header.lch;
return root;
}
s * New_Node(int key) {
s * p_node = new s;
if (!p_node) {
cerr << "Out of memory!" << endl;
exit(1);
}
p_node -> k = key;
p_node -> lch = p_node -> rch = NULL;
return p_node;
}
s * Insert(int key, s * root) {
s * p_node = New_Node(key);
if (!root) return p_node;
root = Splay(key, root);
if (key < root -> k) {
p_node -> lch = root -> lch;
p_node -> rch = root;
root -> lch = NULL;
return p_node;
} else if (key > root -> k) {
p_node -> rch = root -> rch;
p_node -> lch = root;
root -> rch = NULL;
return p_node;
} else {
delete p_node;
return root;
}
}
s * Delete(int key, s * root) {
if (!root) return NULL;
root = Splay(key, root);
if (key != root -> k) return root;
s * temp;
if (!root -> lch) {
temp = root;
root = root -> rch;
} else {
temp = root;
root = Splay(key, root -> lch);
root -> rch = temp -> rch;
}
delete temp;
return root;
}
s * Search(int key, s * root) {
return Splay(key, root);
}
void InOrder(s * root) {
if (root) {
InOrder(root -> lch);
cout << "Key: " << root -> k;
if (root -> lch)
cout << " | Left: " << root -> lch -> k;
if (root -> rch)
cout << " | Right: " << root -> rch -> k;
cout << "\n";
InOrder(root -> rch);
}
}
};
int main() {
SplayTree st;
s * root = NULL;
// Step 1: Insert predefined values
int values[] = {50, 30, 60, 20, 40, 70};
int n = sizeof(values) / sizeof(values[0]);
for (int i = 0; i < n; i++) {
root = st.Insert(values[i], root);
}
cout << "\nInOrder traversal after insertion:\n";
st.InOrder(root);
// Step 2: Search for 40
int searchKey = 40;
cout << "\nSearching for key: " << searchKey << "\n";
root = st.Search(searchKey, root);
if (root && root -> k == searchKey)
cout << "Key " << searchKey << " found at root.\n";
else
cout << "Key " << searchKey << " not found.\n";
cout << "\nTree after search:\n";
st.InOrder(root);
// Step 3: Delete 40
cout << "\nDeleting key: " << searchKey << "\n";
root = st.Delete(searchKey, root);
cout << "\nTree after deletion:\n";
st.InOrder(root);
// Step 4: Search again for 40
cout << "\nSearching again for key: " << searchKey << "\n";
root = st.Search(searchKey, root);
if (root && root -> k == searchKey)
cout << "Key " << searchKey << " still found at root.\n";
else
cout << "Key " << searchKey << " not found (as expected).\n";
cout << "\nFinal Tree State:\n";
st.InOrder(root);
return 0;
}
Following is the output of the code:
InOrder traversal after insertion: Key: 20 Key: 30 | Left: 20 Key: 40 | Left: 30 Key: 50 | Left: 40 Key: 60 | Left: 50 Key: 70 | Left: 60 Searching for key: 40 Key 40 found at root. Tree after search: Key: 20 Key: 30 | Left: 20 Key: 40 | Left: 30 | Right: 60 Key: 50 Key: 60 | Left: 50 | Right: 70 Key: 70 Deleting key: 40 Tree after deletion: Key: 20 Key: 30 | Left: 20 | Right: 60 Key: 50 Key: 60 | Left: 50 | Right: 70 Key: 70 Searching again for key: 40 Key 40 not found (as expected). Final Tree State: Key: 20 Key: 30 | Left: 20 Key: 50 | Left: 30 | Right: 60 Key: 60 | Right: 70 Key: 70