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
Updated on: 2025-05-30T18:39:36+05:30

3K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements