实现要点:每个node持有上下左右四个指针。插入节点时随机生成层数,方法是不断的生成随机数,如果小于0.5则level加一,直到随机数大于0.5为止。根据层数在各层插入相应的节点。
public class SkipList {
private final double POSSIBILITY = 0.5;
private final int MAX_LEVEL = 32;
Random rand = new Random();
private SkipListNode head;
private SkipListNode tail;
private int level;
public SkipList() {
head = new SkipListNode(SkipListNode.MIN);
tail = new SkipListNode(SkipListNode.MAX);
head.right = tail;
tail.left = head;
level = 1;
}
public boolean contains(int key) {
SkipListNode p = findNode(key);
return p.key == key;
}
public void add(int key) {
SkipListNode p = findNode(key);
if (p.key == key) return;
int lev = getLevel();
SkipListNode downNode = null;
for (int i=1; i<=lev; i++) {
if (p == null) {
SkipListNode newHead = new SkipListNode(SkipListNode.MIN);
SkipListNode newTail = new SkipListNode(SkipListNode.MAX);
linkRight(newHead, newTail);
linkUp(head, newHead);
head = newHead;
linkUp(tail, newTail);
tail = newTail;
p = head;
level++;
}
SkipListNode node = new SkipListNode(key);
SkipListNode next = p.right;
linkRight(p, node);
linkRight(node, next);
if (downNode != null) linkUp(downNode, node);
while (!isHead(p) && p.up == null) p = p.left;
p = p.up;
downNode = node;
}
}
public void print() {
SkipListNode p = head;
while (p != null) {
String line = "h->";
SkipListNode cur = p.right;
while (!isTail(cur)) {
line += cur.key + "->";
cur = cur.right;
}
p = p.down;
System.out.println(line);
}
}
private SkipListNode findNode(int key) {
SkipListNode p = head;
while (true) {
while (!isTail(p.right) && p.right.key <= key) p = p.right;
if (p.down == null)
break;
else p = p.down;
}
return p;
}
private boolean isHead(SkipListNode p) {
return p.key == SkipListNode.MIN;
}
private boolean isTail(SkipListNode p) {
return p.key == SkipListNode.MAX;
}
private void linkUp(SkipListNode pre, SkipListNode node) {
pre.up = node;
node.down = pre;
}
private void linkRight(SkipListNode pre, SkipListNode node) {
pre.right = node;
node.left = pre;
}
private int getLevel() {
int ans = 1;
while (rand.nextDouble() < POSSIBILITY && ans < MAX_LEVEL) ans++;
return ans;
}
static class SkipListNode {
static final int MIN = Integer.MIN_VALUE;
static final int MAX = Integer.MAX_VALUE;
int key;
SkipListNode up;
SkipListNode right;
SkipListNode down;
SkipListNode left;
public SkipListNode(int k) {
this.key = k;
}
}
}
网友评论