java跳表实现
概念:一种有序链表,带有多级索引,查询性能为O(logN)。
运用:Redis,ConcurrentSkipListMap
这里主要参照了leetcode的实现,补充了泛型实现。
public class SkipList<T> {
//当前层级
private int curentLevel = 1;
//最大索引层级
private final static int MAX_LEVEL = 32;
//队列头节点
private final Node<T> HEAD = new Node<>(null, MAX_LEVEL);
//晋升几率
private final static double promote = 0.25d;
private Comparator<T> comparator;
public SkipList() {
}
public SkipList(Comparator<T> comparator) {
this.comparator = comparator;
}
public void add(T value) {
if (value == null) {
throw new NullPointerException();
}
int level = getRandomLevel();
Node<T> newNode = new Node<>(value, level);
Node<T> point = HEAD;
for (int current = curentLevel - 1; current >= 0; current--) {
point = findClosest(point, current, value);
if(current < level){
Node<T> oldNext = point.nextArr[current];
point.nextArr[current] = newNode;
newNode.nextArr[current] = oldNext;
}
}
if (level > curentLevel){ //如果随机出来的层数比当前的层数还大,那么超过currentLevel的head 直接指向newNode
for (int i = curentLevel; i < level; i++) {
HEAD.nextArr[i] = newNode;
}
curentLevel = level;
}
}
public boolean search(T value) {
if (value == null) {
return false;
}
Node<T> point = HEAD;
for (int current = curentLevel - 1; current >= 0; current--) {
point = findClosest(point, current, value);
if(point.nextArr[current] != null && point.nextArr[current].value.equals(value)){
return true;
}
}
return false;
}
public boolean erase(T value) {
if (value == null) {
return false;
}
boolean flag = false;
Node<T> point = HEAD;
for (int current = curentLevel - 1; current >= 0; current--) {
point = findClosest(point, current, value);
if(point.nextArr[current] != null && point.nextArr[current].value.equals(value)){
point.nextArr[current] = point.nextArr[current].nextArr[current];
flag = true;
}
}
return flag;
}
private Node<T> findClosest(Node<T> point, int level, T value) {
Node<T> node = point;
while (true) {
Node<T> next = node.nextArr[level];
if (next == null || cpr(next.value, value) >= 0) {
break;
} else {
node = next;
}
}
return node;
}
private int getRandomLevel() {
int initLevel = 1;
while (Math.random() <= promote && initLevel < MAX_LEVEL) {
initLevel++;
}
return initLevel;
}
private int cpr(T a, T b) {
if (comparator != null) {
return comparator.compare(a, b);
} else {
Comparable<T> comparable = (Comparable<T>) a;
return comparable.compareTo(b);
}
}
class Node<T> {
T value;
Node<T>[] nextArr;
Node(T value, int size) {
this.value = value;
this.nextArr = new Node[size];
}
}
}