📅  最后修改于: 2023-12-03 14:47:32.022000             🧑  作者: Mango
Splay Tree is a self-adjusting binary search tree with the property that recently accessed elements are quick to access again. In this article, we will discuss the implementation of Splay Tree in Java.
The first step is to define a Node class, which will represent the nodes of the Splay Tree. Each node will have a key, a left child, a right child, and a parent.
class Node {
int key;
Node left;
Node right;
Node parent;
Node(int key) {
this.key = key;
this.left = null;
this.right = null;
this.parent = null;
}
}
The Splay Tree class will contain the root node of the tree and methods to insert, delete and search for a node. The constructor will initialize the root to null.
class SplayTree {
Node root;
SplayTree() {
root = null;
}
}
The Splay Tree uses rotations to maintain the tree structure. There are three types of rotations - zig, zig-zig, and zig-zag. The zig rotation is a simple left or right rotation. The zig-zig rotation involves two consecutive left or right rotations, and the zig-zag rotation involves a left rotation followed by a right rotation or a right rotation followed by a left rotation.
class SplayTree {
//...
void zig(Node x) {
Node y = x.parent;
if (y.left == x) {
Node b = x.right;
x.right = y;
y.left = b;
} else {
Node b = x.left;
x.left = y;
y.right = b;
}
x.parent = y.parent;
y.parent = x;
if (x.parent != null) {
if (x.parent.left == y) {
x.parent.left = x;
} else {
x.parent.right = x;
}
}
}
void zigZig(Node x) {
Node y = x.parent;
Node z = y.parent;
if (y.left == x) {
Node b = x.right;
Node c = y.right;
x.right = y;
y.left = b;
y.right = z;
z.left = c;
} else {
Node b = x.left;
Node c = y.left;
x.left = y;
y.right = b;
y.left = z;
z.right = c;
}
x.parent = z.parent;
y.parent = x;
z.parent = y;
if (x.parent != null) {
if (x.parent.left == z) {
x.parent.left = x;
} else {
x.parent.right = x;
}
}
}
void zigZag(Node x) {
Node y = x.parent;
Node z = y.parent;
if (y.left == x) {
Node b = x.right;
Node c = x.left;
x.left = y;
y.right = c;
x.right = z;
z.left = b;
} else {
Node b = x.left;
Node c = x.right;
x.right = y;
y.left = c;
x.left = z;
z.right = b;
}
x.parent = z.parent;
y.parent = x;
z.parent = x;
if (x.parent != null) {
if (x.parent.left == z) {
x.parent.left = x;
} else {
x.parent.right = x;
}
}
}
}
The Splay operation is the heart of the Splay Tree. It takes a node as input and brings it to the root of the tree by performing a series of rotations. The Splay operation has three main cases:
class SplayTree {
//...
void splay(Node x) {
while (x.parent != null) {
Node y = x.parent;
Node z = y.parent;
if (z == null) {
zig(x);
} else if ((z.left == y && y.left == x) || (z.right == y && y.right == x)) {
zigZig(x);
} else {
zigZag(x);
}
}
root = x;
}
}
The search operation in Splay Tree works by first performing a regular binary search for the key and then splaying the node to the root. If the key is not found, we splay the last accessed node to the root.
class SplayTree {
//...
Node search(int key) {
Node x = root;
Node y = null;
while (x != null) {
if (key < x.key) {
y = x;
x = x.left;
} else if (key > x.key) {
y = x;
x = x.right;
} else {
splay(x);
return x;
}
}
if (y != null) {
splay(y);
}
return null;
}
}
The insert operation in Splay Tree works by first performing a regular binary search for the key and then inserting the node in the appropriate position. After insertion, we splay the inserted node to the root.
class SplayTree {
//...
void insert(int key) {
if (root == null) {
root = new Node(key);
} else {
Node x = root;
Node y = null;
while (x != null) {
y = x;
if (key < x.key) {
x = x.left;
} else if (key > x.key) {
x = x.right;
} else {
return;
}
}
Node z = new Node(key);
z.parent = y;
if (key < y.key) {
y.left = z;
} else {
y.right = z;
}
splay(z);
}
}
}
The delete operation in Splay Tree works by first performing a search for the key to be deleted and then deleting the node as we would in a regular binary search tree. After deletion, we splay the parent of the deleted node to the root.
class SplayTree {
//...
void delete(int key) {
Node x = search(key);
if (x == null) {
return;
}
if (x.left != null && x.right != null) {
Node y = x.right;
while (y.left != null) {
y = y.left;
}
x.key = y.key;
x = y;
}
Node z;
if (x.left != null) {
z = x.left;
} else {
z = x.right;
}
if (z != null) {
z.parent = x.parent;
}
if (x.parent == null) {
root = z;
} else if (x == x.parent.left) {
x.parent.left = z;
splay(x.parent.left);
} else {
x.parent.right = z;
splay(x.parent.right);
}
}
}
In this article, we discussed the implementation of Splay Tree in Java. We defined a Node class to represent the nodes of the tree, and a SplayTree class to contain the root node and methods to perform operations on the tree. We also discussed the various rotations used in Splay Tree and the Splay operation, which brings a node to the root of the tree. Finally, we implemented the insert, search, and delete operations in the SplayTree class.