# 跳表 skiplist

myshell

## 跳表简介

Skip lists are a data structure that can be used in place of balanced trees.
Skip lists use probabilistic balancing rather than strictly enforced balancing and as a result the algorithms for insertion and deletion in skip lists are much simpler and significantly faster than equivalent algorithms for balanced trees.

## 跳表的算法

``````public class SkipList<T> {

// 最高层数
private final int MAX_LEVEL;
// 当前层数
private int listLevel;
// 表头
// 表尾
private SkipListNode<T> NIL;
// 生成randomLevel用到的概率值
private final double P;
// 论文里给出的最佳概率值
private static final double OPTIMAL_P = 0.25;

public SkipList() {
// 0.25, 15
this(OPTIMAL_P, (int)Math.ceil(Math.log(Integer.MAX_VALUE) / Math.log(1 / OPTIMAL_P)) - 1);
}

public SkipList(double probability, int maxLevel) {
P = probability;
MAX_LEVEL = maxLevel;

listLevel = 1;
listHead = new SkipListNode<T>(Integer.MIN_VALUE, null, maxLevel);
NIL = new SkipListNode<T>(Integer.MAX_VALUE, null, maxLevel);
for (int i = listHead.forward.length - 1; i >= 0; i--) {
}
}

// 内部类
class SkipListNode<T> {
int key;
T value;
SkipListNode[] forward;

public SkipListNode(int key, T value, int level) {
this.key = key;
this.value = value;
this.forward = new SkipListNode[level];
}
}
}``````

## 搜索

### 插入和删除

##### 1. 插入

randomLevel只依赖于跳表的最高层数和概率值p。算法在后面的代码中。

### java版代码

``````public class SkipList<T> {

// 最高层数
private final int MAX_LEVEL;
// 当前层数
private int listLevel;
// 表头
// 表尾
private SkipListNode<T> NIL;
// 生成randomLevel用到的概率值
private final double P;
// 论文里给出的最佳概率值
private static final double OPTIMAL_P = 0.25;

public SkipList() {
// 0.25, 15
this(OPTIMAL_P, (int)Math.ceil(Math.log(Integer.MAX_VALUE) / Math.log(1 / OPTIMAL_P)) - 1);
}

public SkipList(double probability, int maxLevel) {
P = probability;
MAX_LEVEL = maxLevel;

listLevel = 1;
listHead = new SkipListNode<T>(Integer.MIN_VALUE, null, maxLevel);
NIL = new SkipListNode<T>(Integer.MAX_VALUE, null, maxLevel);
for (int i = listHead.forward.length - 1; i >= 0; i--) {
}
}

// 内部类
class SkipListNode<T> {
int key;
T value;
SkipListNode[] forward;

public SkipListNode(int key, T value, int level) {
this.key = key;
this.value = value;
this.forward = new SkipListNode[level];
}
}

public T search(int searchKey) {

for (int i = listLevel; i > 0; i--) {
while (curNode.forward[i].key < searchKey) {
curNode = curNode.forward[i];
}
}

if (curNode.key == searchKey) {
return curNode.value;
} else {
return null;
}
}

public void insert(int searchKey, T newValue) {
SkipListNode<T>[] update = new SkipListNode[MAX_LEVEL];

for (int i = listLevel - 1; i >= 0; i--) {
while (curNode.forward[i].key < searchKey) {
curNode = curNode.forward[i];
}
// curNode.key < searchKey <= curNode.forward[i].key
update[i] = curNode;
}

curNode = curNode.forward[0];

if (curNode.key == searchKey) {
curNode.value = newValue;
} else {
int lvl = randomLevel();

if (listLevel < lvl) {
for (int i = listLevel; i < lvl; i++) {
}
listLevel = lvl;
}

SkipListNode<T> newNode = new SkipListNode<T>(searchKey, newValue, lvl);

for (int i = 0; i < lvl; i++) {
newNode.forward[i] = update[i].forward[i];
update[i].forward[i] = newNode;
}
}
}

public void delete(int searchKey) {
SkipListNode<T>[] update = new SkipListNode[MAX_LEVEL];

for (int i = listLevel - 1; i >= 0; i--) {
while (curNode.forward[i].key < searchKey) {
curNode = curNode.forward[i];
}
// curNode.key < searchKey <= curNode.forward[i].key
update[i] = curNode;
}

curNode = curNode.forward[0];

if (curNode.key == searchKey) {
for (int i = 0; i < listLevel; i++) {
if (update[i].forward[i] != curNode) {
break;
}
update[i].forward[i] = curNode.forward[i];
}

while (listLevel > 0 && listHead.forward[listLevel - 1] == NIL) {
listLevel--;
}
}
}

private int randomLevel() {
int lvl = 1;
while (lvl < MAX_LEVEL && Math.random() < P) {
lvl++;
}
return lvl;
}

public void print() {
for (int i = listLevel - 1; i >= 0; i--) {
while (curNode != NIL) {
System.out.print(curNode.key + "->");
curNode = curNode.forward[i];
}
System.out.println("NIL");
}
}

public static void main(String[] args) {
SkipList<Integer> sl = new SkipList<Integer>();
sl.insert(20, 20);
sl.insert(5, 5);
sl.insert(10, 10);
sl.insert(1, 1);
sl.insert(100, 100);
sl.insert(80, 80);
sl.insert(60, 60);
sl.insert(30, 30);
sl.print();
System.out.println("---");
sl.delete(20);
sl.delete(100);
sl.print();
}
}``````

55 声望
2 粉丝
0 条评论