public class SkipList {
public int height;
public int size;
public Random random = new Random();
public Node head = new Node(0, null, true);
public static class Node {
public int key;
public String value;
public boolean isHeadNode = false;
public Node left;
public Node right;
public Node up;
public Node down;
public Node(int key, String value) {
this.key = key;
this.value = value;
}
public Node(int key, String value, boolean isHeadNode) {
this.key = key;
this.value = value;
this.isHeadNode = isHeadNode;
}
@Override
public String toString() {
return "Node{" +
"key=" + key +
", value='" + value + '\'' +
", isHeadNode=" + isHeadNode +
'}';
}
}
public Node findEntry(int key) {
Node curr = head;
while (true) {
while (curr.right != null && key >= curr.right.key) {
curr = curr.right;
}
if (curr.down != null) {
curr = curr.down;
} else {
break;
}
}
return curr;
}
public String get(int key) {
Node target = findEntry(key);
return !target.isHeadNode && target.key == key ? target.value : null;
}
public String put(int key, String value) {
Node target = findEntry(key);
//update exist node value
if (!target.isHeadNode && target.key == key) {
String oldValue = target.value;
target.value = value;
return oldValue;
}
//create new node at bottom list
Node newNode = new Node(key, value);
newNode.left = target;
newNode.right = target.right;
if (target.right != null) {
target.right.left = newNode;
}
target.right = newNode;
Node preBaseNode = newNode;
int currLevel = 0;
while (random.nextDouble() > 0.5) {
//create new level
if (currLevel >= this.height) {
Node newHead = new Node(0, null, true);
newHead.down = head;
head.up = newHead;
head = newHead;
Node newLevelNode = new Node(key, value);
newLevelNode.left = newHead;
newHead.right = newLevelNode;
newLevelNode.down = preBaseNode;
preBaseNode.up = newLevelNode;
preBaseNode = newLevelNode;
this.height++;
} else {
//insert node in up level
while (target.up == null) {
target = target.left;
}
target = target.up;
//left right pointer
Node newLevelNode = new Node(key, value);
newLevelNode.left = target;
newLevelNode.right = target.right;
if (target.right != null) {
target.right.left = newLevelNode;
}
target.right = newLevelNode;
//up down pointer
newLevelNode.down = preBaseNode;
preBaseNode.up = newLevelNode;
preBaseNode = newLevelNode;
}
currLevel++;
}
this.size++;
return null;
}
public String remove(int key) {
Node target = findEntry(key);
if (target.isHeadNode || target.key != key) {
return null;
}
String value = target.value;
while (target != null) {
target.left.right = target.right;
if (target.right != null) {
target.right.left = target.left;
}
target = target.up;
}
return value;
}
public void print() {
Node p = head;
while (p != null) {
System.out.print(p.key);
Node curr = p;
while (curr.right != null) {
if (curr.right.down != null && curr.right.down.key != curr.right.key) {
throw new IllegalStateException(curr.right.key + " != " + curr.right.down.key);
}
System.out.print(" -> " + curr.right.key);
curr = curr.right;
}
System.out.println();
p = p.down;
}
}
public static void main(String[] args) {
SkipList skipList = new SkipList();
//put
skipList.put(3, "(3)");
skipList.put(10, "(10)");
skipList.put(1, "(1)");
skipList.put(2, "(2)");
skipList.put(5, "(5)");
skipList.put(8, "(8)");
skipList.put(9, "(9)");
skipList.put(6, "(6)");
skipList.print();
//get
System.out.println("skip list size:" + skipList.size);
System.out.println("skip list height:" + skipList.height);
System.out.println("search 5:" + skipList.get(5));
System.out.println("search 4:" + skipList.get(4));
//remove
System.out.println("remove 5:" + skipList.remove(5));
System.out.println("search 5:" + skipList.get(5));
}
}
Skip List基本操作
最新推荐文章于 2020-06-03 17:08:35 发布