summarize
SkipList is a data structure consisting of a chained table plus a multilevel index. The query complexity of the data structure of a chained table is O(N). In order to improve the query efficiency, you can add multi-level indexes on the chained table to realize fast query. Jumping tables not only improve the search performance. It also improves the performance of insertion and deletion operations. The number of levels of the index is also called the height of the jump table
find
In the structure of a jump table, the search starts at the top level, and when the top level does not exist, it goes to the next level, and repeats this process until it jumps to the original linked table. As shown in the figure, to find 10 in the chain table of [1,3,4,10,1,20], we first look up at the second level index, and since both 1 and 4 are smaller than 10, we then look up at the first level index, and since 10 is larger than 4 and smaller than 11, we then look down, and the next node of 4 in the original chain table, 10, is the data we need to look up.
stick
First find the predecessor and successor of the element to be inserted according to the lookup process, then generate a height value according to the randomized algorithm, and finally generate a vertical node according to the height value (the number of layers of this node is exactly equal to the height value) from the node to be inserted, and insert it into the multi-linked table of the jump table. If the height value heigh is greater than the height of the jump table before insertion, then the height of the jump table is raised to height, and the pointers to the head and tail nodes need to be updated. If height is less than or equal to the height of the jump table, then the pointers to the predecessors and successors of the element to be inserted are updated. The process of inserting 18 into the jump table of [1,3,4.10,11,20] is shown in the following figure.
removing
When deleting a node, you first need to find the predecessor and successor of the node to be deleted at each level, and then replace the successor of the predecessor node with the successor of the node to be deleted, and the process of deleting 4 is shown in Fig.
code implementation
import ;
import ;
class SkipNode<T> {
int key; T value; {
T value; { int
SkipNode right,down;// Pointer to the left, right, up, down and four directions.
public SkipNode (int key,T value) {
=key; =value; //SkipNode
=value; }
}
}
public class SkipList <T> {
SkipNode headNode;//head node, entrance
int highLevel;// number of levels
Random random;// for coin tossing
final int MAX_LEVEL = 32;// maxLevel
SkipList(){
random=new Random(); headNode=new SkipNode
headNode=new SkipNode(Integer.MIN_VALUE,null);
headNode=new SkipNode(Integer.MIN_VALUE,null); highLevel=0;
}
public SkipNode search(int key) {
SkipNode team=headNode; while (team!=null) { team!=null)
while (team!=null) {
while (team!=null) { if(==key){
if(== key){ if(== key){ return team; }
}
else if(==null) { //right side is gone, can only go down
team=;
}
else if(>key) { //need to descend to find
team=;
}
else { //right side is smaller to the right
team=;
}
}
return null; }
}
public void delete(int key) { //delete without considering the number of layers
SkipNode team=headNode;
while (team!=null) {
if ( == null) { // no more on the right side, that means this layer is found, no can only descend
team=;
}
else if(==key) { //find the node, the right side is the node to be deleted.
=; // Delete the right node.
team=; //Delete the node on the right side.
}
else if(>key) { //right side is no longer possible, go down
team=;
}
else { //node still on the right
team=;
}
}
}
public void add(SkipNode node) {
int key=;
SkipNode findNode=search(key);
if(findNode!=null) { //If a node with this key exists, add it to the list.
=; return; if(findNode!
return;
}
Stack<SkipNode>stack=new Stack<SkipNode>();//store down nodes which may insert nodes on the right side
SkipNode team=headNode;// Find the node to be inserted Find which node is at the bottom.
while (team!=null) {// Perform a lookup operation
if (==null) { //there are no more on the right side, it can only go down
(team);//keep a record of the nodes that were once down
team=;
}
else if(>key) { //need to descend to find
(team);//record the nodes that have been down before
team=; }
}
else { //go to the right
team=;
}
}
int level=1;//current level, add from the first level (the first level must be added, first add then judge)
SkipNode downNode=null;//keep the predecessor node (i.e. down's pointing, initially null)
while (! ()) {
// Insert node at that level
team=();//throw the left node to be inserted
SkipNode nodeTeam=new SkipNode(, );//node needs to be recreated
= downNode;// Handle vertical direction
downNode=nodeTeam;// mark the new node for next use
if(==null) {// A null on the right side means the insertion is at the end
=nodeTeam;
}
//Horizontal processing
else {// There are still nodes on the right side, insert between the two
=;
=nodeTeam; }
}
//consider if we need to go up
if(level>MAX_LEVEL)//have already reached the highest level node
break; double num=()
double num=();//[0-1] random number
if(num>0.5)//bad luck end
break;
if(num>0.5)//bad luck end break; level++;
if(level>highLevel) { //higher than current max height but still within allowed range need to change head node
highLevel=level;
//need to create a new node
SkipNode highHeadNode=new SkipNode(Integer.MIN_VALUE, null); //Create a new node.
= headNode.
headNode=highHeadNode;//change head
(headNode);// next time throw head
}
}
}
public void printList() {
SkipNode teamNode=headNode; int index=1;
SkipNode last=teamNode; while (!
while (! =null){
teamNode=headNode; int index=1; SkipNode last=teamNode; while (!
}
while (teamNode!=null) {
SkipNode enumNode=;
SkipNode enumLast=;
("%-8s", "head->");
while (enumLast!=null&&enumNode!=null) {
if(==) {
("%-5s",+"->");
enumLast=;
enumNode=;
}
else {
enumLast=;; ("%-5s","); enumNode=; } else {
("%-5s",""); }
}
}
teamNode=;.
teamNode=;; index++;
(); }
}
}
}