Introduction To Splay Tree Data Structure
Introduction To Splay Tree Data Structure
Splay tree is a self-adjusting binary search tree data structure, which means that the tree structure
is adjusted dynamically based on the accessed or inserted elements. In other words, the tree
automatically reorganizes itself so that frequently accessed or inserted elements become closer to
the root node.
1. The splay tree was first introduced by Daniel Dominic Sleator and Robert Endre Tarjan in
1985. It has a simple and efficient implementation that allows it to perform search,
insertion, and deletion operations in O(log n) amortized time complexity, where n is the
number of elements in the tree.
2. The basic idea behind splay trees is to bring the most recently accessed or inserted
element to the root of the tree by performing a sequence of tree rotations, called splaying.
Splaying is a process of restructuring the tree by making the most recently accessed or
inserted element the new root and gradually moving the remaining nodes closer to the
root.
3. Splay trees are highly efficient in practice due to their self-adjusting nature, which reduces
the overall access time for frequently accessed elements. This makes them a good choice
for applications that require fast and dynamic data structures, such as caching systems,
data compression, and network routing algorithms.
4. However, the main disadvantage of splay trees is that they do not guarantee a balanced
tree structure, which may lead to performance degradation in worst-case scenarios. Also,
splay trees are not suitable for applications that require guaranteed worst-case
performance, such as real-time systems or safety-critical systems.
Overall, splay trees are a powerful and versatile data structure that offers fast and efficient access
to frequently accessed or inserted elements. They are widely used in various applications and
provide an excellent tradeoff between performance and simplicity.
A splay tree is a self-balancing binary search tree, designed for efficient access to data elements
based on their key values.
The key feature of a splay tree is that each time an element is accessed, it is moved to the
root of the tree, creating a more balanced structure for subsequent accesses.
Splay trees are characterized by their use of rotations, which are local transformations of
the tree that change its shape but preserve the order of the elements.
Rotations are used to bring the accessed element to the root of the tree, and also to
rebalance the tree if it becomes unbalanced after multiple accesses.
Insertion: To insert a new element into the tree, start by performing a regular binary
search tree insertion. Then, apply rotations to bring the newly inserted element to the root
of the tree.
Deletion: To delete an element from the tree, first locate it using a binary search tree
search. Then, if the element has no children, simply remove it. If it has one child, promote
that child to its position in the tree. If it has two children, find the successor of the element
(the smallest element in its right subtree), swap its key with the element to be deleted,
and delete the successor instead.
Search: To search for an element in the tree, start by performing a binary search tree
search. If the element is found, apply rotations to bring it to the root of the tree. If it is not
found, apply rotations to the last node visited in the search, which becomes the new root.
Rotation: The rotations used in a splay tree are either a Zig or a Zig-Zig rotation. A Zig
rotation is used to bring a node to the root, while a Zig-Zig rotation is used to balance the
tree after multiple accesses to elements in the same subtree.
Zig Rotation: If a node has a right child, perform a right rotation to bring it to the root. If it
has a left child, perform a left rotation.
Zig-Zig Rotation: If a node has a grandchild that is also its child’s right or left child, perform
a double rotation to balance the tree. For example, if the node has a right child and the
right child has a left child, perform a right-left rotation. If the node has a left child and the
left child has a right child, perform a left-right rotation.
Note: The specific implementation details, including the exact rotations used, may vary
depending on the exact form of the splay tree.
Zig Rotation
Zag Rotation
1) Zig Rotation:
The Zig Rotation in splay trees operates in a manner similar to the single right rotation in AVL Tree
rotations. This rotation results in nodes moving one position to the right from their current
location. For example, consider the following scenario:
Zig Rotation (Single Rotation)
2) Zag Rotation:
The Zag Rotation in splay trees operates in a similar fashion to the single left rotation in AVL Tree
rotations. During this rotation, nodes shift one position to the left from their current location. For
instance, consider the following illustration:
3) Zig-Zig Rotation:
The Zig-Zig Rotation in splay trees is a double zig rotation. This rotation results in nodes shifting
two positions to the right from their current location. Take a look at the following example for a
better understanding:
Zig-Zig Rotation (Double Right Rotation)
4) Zag-Zag Rotation:
In splay trees, the Zag-Zag Rotation is a double zag rotation. This rotation causes nodes to move
two positions to the left from their present position. For example:
5) Zig-Zag Rotation:
The Zig-Zag Rotation in splay trees is a combination of a zig rotation followed by a zag rotation. As
a result of this rotation, nodes shift one position to the right and then one position to the left from
their current location. The following illustration provides a visual representation of this concept:
Zig- Zag rotation
6) Zag-Zig Rotation:
The Zag-Zig Rotation in splay trees is a series of zag rotations followed by a zig rotation. This results
in nodes moving one position to the left, followed by a shift one position to the right from their
current location. The following illustration offers a visual representation of this concept:
Zag-Zig Rotation
Splay Tree-
Splay tree is a binary search tree. In a splay tree, M consecutive operations can be performed in O (M
log N) time.
A single operation may require O(N) time but average time to perform M operations will need O (M
Log N) time.
When a node is accessed, it is moved to the top through a set of operations known as splaying.
Splaying technique is similar to rotation in an AVL tree. This will make the future access of the node
cheaper.
Unlike AVL tree, splay trees do not have the requirement of storing Balance Factor of every node.
This saves the space and simplifies algorithm to a great extent.
1. Bottom up Splaying
1. Bottom up Splaying:-
Idea behind bottom up splaying is explained below: Rotation is performed bottom up along the
access path.
Let X be a (non root) node on the access path at which we are rotating.
a) If the parent of X is the root of the tree, rotate X and the parent of X. This will be the last rotation
required.
b) If X has both a parent (P) and Grand parent (G) then like an AVL tree there could be four cases.
When an item X is inserted as a leaf, a series of tree rotations brings X at the root. These rotations
are known as splaying. A splay is also performed during searches, and if an item is not found, a splay
is performed on the last node on the access path.
This can be done by storing the access path, during top down traversal on a stack.
Top down splaying is based on splaying on the initial traversal path. A stack is not required to save
the traversal path.
1. A current node X that is the root of its sub tree and represented as the “middle” tree.
2. Tree L stores nodes in the tree T that are less than X, but not in the X’s sub tree.
3. Tree R stores nodes in the tree T that are larger than X, but not in X’s sub tree.
y x
x T3 – - – - – - – - - -> T1 y
/\ <--------- /\
3) Node has both parent and grandparent. There can be following subcases.
……..3.a) Zig-Zig and Zag-Zag Node is left child of parent and parent is also left child of grand parent
(Two right rotations) OR node is right child of its parent and parent is also right child of grand parent
(Two Left Rotations).
G P X
/\ / \ /\
P T4 rightRotate(G) X G rightRotate(P) T1 P
/\ ============> / \ / \ ============> /\
X T3 T1 T2 T3 T4 T2 G
/\ /\
T1 T2 T3 T4
G P X
/ \ / \ /\
T1 P leftRotate(G) G X leftRotate(P) P T4
/ \ ============> / \ / \ ============> / \
T2 X T1 T2 T3 T4 G T3
/\ /\
T3 T4 T1 T2
……..3.b) Zig-Zag and Zag-Zig Node is right child of parent and parent is left child of grand parent (Left
Rotation followed by right rotation) OR node is left child of its parent and parent is right child of
grand parent (Right Rotation followed by left rotation).
G G X
/\ / \ / \
P T4 leftRotate(P) X T4 rightRotate(G) P G
/ \ ============> / \ ============> / \ / \
T1 X P T3 T1 T2 T3 T4
/\ /\
T2 T3 T1 T2
G G X
/ \ / \ / \
T1 P rightRotate(P) T1 X leftRotate(G) G P
/ \ =============> / \ ============> / \ / \
X T4 T2 P T1 T2 T3 T4
/\ /\
T2 T3 T3 T4
Example:
/ \ / \ \
50 200 50 200 50
/ search(20) / search(20) / \
/ 1. Zig-Zig \ 2. Zig-Zig \ \
30 at 40 30 at 100 40 200
/ \
[20] 40
class Node:
self.key = key
self.left = None
self.right = None
def new_node(key):
return Node(key)
def right_rotate(x):
y = x.left
x.left = y.right
y.right = x
return y
def left_rotate(x):
y = x.right
x.right = y.left
y.left = x
return y
if root is None :
return new_node(key)
if root.key == key:
return root
if root.left is None:
return root
root = right_rotate(root)
if root.left.right:
root.left = left_rotate(root.left)
else:
if root.right is None:
return root
if root.right.left:
root.right = right_rotate(root.right)
root = left_rotate(root)
if root is None:
return new_node(key)
if root.key == key:
return root
node = new_node(key)
node.right = root
node.left = root.left
root.left = None
else:
node.left = root
node.right = root.right
root.right = None
return node
def pre_order(node):
if node:
pre_order(node.left)
pre_order(node.right)
if __name__ == "__main__":
root = None
pre_order(root)