Splay Tree
A splay tree is a self-adjusting binary search tree where recently accessed elements are quick to access again via rotations. It works by splaying accessed nodes to the root.
Java example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
| class Node {
int key;
Node left, right;
public Node(int item) {
key = item;
}
}
Node splay(Node root, int key) {
if (root == null || root.key == key) {
return root;
}
if (key < root.key) {
// key in left subtree
if (root.left == null) {
return root;
}
// Zig-zag splay
if (key < root.left.key) {
// Rotate right child
root.left.right = splay(root.left.right, key);
// new right child
root = rotateLeft(root);
}
// Zag-zig splay
else if (key > root.left.key) {
root = rotateRight(root);
}
// Zig-zig splay
return rotateLeft(root);
}
// Mirror image logic for right subtree
}
|
C++ example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
| struct Node {
int key;
Node *left, *right;
Node(int k) : key(k) {}
};
Node* splay(Node* root, int key) {
if (!root || root->key == key) {
return root;
}
// Key in left subtree
if (key < root->key) {
//Recurse
if (!root->left) return root;
// Zig-zag rotation
if (key < root->left->key) {
root->left->right = splay(root->left->right, key);
root = rightRotate(root);
}
// Zag-zig rotation
else if (key > root->left->key) {
root = leftRotate(root);
}
// Zig-zig rotation
return rightRotate(root);
}
// Mirror image logic for right subtree
return root;
}
|
Python example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| class Node:
def __init__(self, key):
self.key = key
self.left = self.right = None
def splay(root, key):
if not root or root.key == key:
return root
if key < root.key:
# Key in left subtree
if not root.left:
return root
# Zig-zag rotation
if key < root.left.key:
root.left.right = splay(root.left.right, key)
root = rightRotate(root)
# Zag-zig rotation
elif key > root.left.key:
root = leftRotate(root)
# Zig-zig rotation
return rightRotate(root)
# Mirror image logic for right subtree
return root
|
Splay trees dynamically restructure on access to improve future access time. Useful for caches and priority queues.
A Splay Tree is a self-adjusting binary search tree. Every time an operation like insertion, deletion, or search is performed, the tree is rearranged so that the node corresponding to that operation becomes the new root. This action is known as “splaying.” Splay Trees don’t guarantee constant log time for each operation but perform quite well in practice for access patterns with locality of reference.
Java Code for Splay Tree
Here’s a simplified Java example for inserting a node and splaying:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
| class Node {
int key;
Node left, right;
}
class SplayTree {
Node root;
// Splay operation
private Node splay(Node root, int key) {
// Base cases
if (root == null || root.key == key) return root;
if (root.key > key) {
// Key is in the left subtree
if (root.left == null) return root;
// Splay the left child
root.left = splay(root.left, key);
// Rotate right
return rightRotate(root);
} else {
// Key is in the right subtree
if (root.right == null) return root;
// Splay the right child
root.right = splay(root.right, key);
// Rotate left
return leftRotate(root);
}
}
// Right rotation
private Node rightRotate(Node x) {
Node y = x.left;
x.left = y.right;
y.right = x;
return y;
}
// Left rotation
private Node leftRotate(Node x) {
Node y = x.right;
x.right = y.left;
y.left = x;
return y;
}
// Insert operation
public void insert(int key) {
root = insert(root, key);
}
private Node insert(Node root, int key) {
if (root == null) return new Node(key);
root = splay(root, key);
// Insert the new node
Node newNode = new Node(key);
if (key < root.key) {
newNode.right = root;
newNode.left = root.left;
root.left = null;
} else {
newNode.left = root;
newNode.right = root.right;
root.right = null;
}
return newNode;
}
}
|
C++ Code for Splay Tree
Here’s the C++ code snippet:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
| struct Node {
int key;
Node *left, *right;
};
Node* rightRotate(Node *x) {
Node *y = x->left;
x->left = y->right;
y->right = x;
return y;
}
Node* leftRotate(Node *x) {
Node *y = x->right;
x->right = y->left;
y->left = x;
return y;
}
Node* splay(Node *root, int key) {
// Base cases and splay logic similar to Java example
// ...
}
Node* insert(Node *root, int key) {
// Insertion logic similar to Java example
// ...
}
|
Python Code for Splay Tree
Python code snippet:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| class Node:
def __init__(self, key):
self.key = key
self.left = None
self.right = None
def rightRotate(x):
y = x.left
x.left = y.right
y.right = x
return y
def leftRotate(x):
y = x.right
x.right = y.left
y.left = x
return y
def splay(root, key):
# Base cases and splay logic similar to Java example
# ...
def insert(root, key):
# Insertion logic similar to Java example
# ...
|
In all three implementations, the splay()
function restructures the tree by moving the node associated with a given key to the root. The insert()
function inserts a new node and then splays it to the root. Both right and left rotations are also implemented.