public class SkipList {
/**
* 节点晋升索引的概率
*/
private static final double PROMOTE_RATE = 0.5;
/**
* 描述跳表中头节点,哨兵
*/
private Node head;
/**
* 描述跳表中尾节点,哨兵
*/
private Node tail;
/**
* 当前索引层的高度
*/
private int level;
/**
* 初始化链表
*/
public SkipList() {
this.head = new Node(Integer.MIN_VALUE);
this.tail = new Node(Integer.MAX_VALUE);
head.next = tail;
tail.prev = head;
}
/**
* 查找数据
*
* @param data
* @return
*/
public Node search(int data) {
Node res = null;
Node findedNode = findNode(data);
if (findedNode.data == data) {
res = findedNode;
}
return res;
}
/**
* 通过data来查找节点
*
* @param data
* @return
*/
private Node findNode(int data) {
Node curNode = head;
while (true) {
while (curNode.next.data != Integer.MAX_VALUE && curNode.next.data <= data) {
curNode = curNode.next;
}
if (curNode.down == null) {
break;
}
curNode = curNode.down;
}
return curNode;
}
/**
* 插入数据
*
* @param data
*/
public void insert(int data) {
//查找数据是否已存在于跳表
Node preNode = findNode(data);
if (preNode.data == data) {
return;
}
//不存在,进行插入
Node node = new Node(data);
addNodeToNext(preNode,node);
int curLevel = 0;
while (Math.random() > PROMOTE_RATE) {
if (curLevel == level) {
if(head.next.data == data && tail.prev.data == data){
break;
}
incrLevel();
}
while (preNode.up == null) {
preNode = preNode.prev;
}
preNode = preNode.up;
Node indexNode = new Node(data);
addNodeToNext(preNode, indexNode);
node.up = indexNode;
indexNode.down = node;
node = indexNode;
curLevel++;
}
}
/**
* 删除数据
*
* @param data
* @return
*/
public boolean delete(int data) {
//查找数据是否存在
Node node = search(data);
if (node == null) {
return false;
}
//存在则删除
removeNode(node,0);
int curLevel = 1;
while ((node = node.up) != null) {
removeNode(node,curLevel);
curLevel++;
}
return true;
}
/**
* 删除一个节点
*
* @param node
*/
private void removeNode(Node node,int curLevel) {
Node prev = node.prev;
Node next = node.next;
prev.next = next;
next.prev = prev;
if(prev.data == Integer.MIN_VALUE && next.data == Integer.MAX_VALUE && curLevel!=0){
node.up = null;
decrLevel(curLevel,prev,next);
}
}
/**
* 从该层降级
*/
private void decrLevel(int curLevel,Node first,Node last){
level = --curLevel;
head = first.down;
tail = last.down;
//help gc
head.up=null;
tail.up=null;
}
/**
* 按顺序打印SkipList的所有数据
*/
public void printList(){
Node node = head;
while(node.down!=null){
node = node.down;
}
node = node.next;
while(node.data!= Integer.MAX_VALUE){
System.out.print(node.data + " ");
node = node.next;
}
System.out.println();
}
/**
* 添加一个节点到指定节点的右侧
*
* @param preNode
* @param node
*/
public void addNodeToNext(Node preNode, Node node) {
Node next = preNode.next;
preNode.next = node;
node.prev = preNode;
node.next = next;
next.prev = node;
}
/**
* 增加一层索引
*/
public void incrLevel() {
++level;
Node p1 = new Node(Integer.MIN_VALUE);
Node p2 = new Node(Integer.MAX_VALUE);
p1.next = p2;
p2.prev = p1;
head.up = p1;
p1.down = head;
head = p1;
tail.up = p2;
p2.down = tail;
tail = p2;
}
/**
* 跳表中的节点
*/
class Node {
int data;
Node prev, next, up, down;
public Node(int data) {
this.data = data;
}
}
public static void main(String[] args) {
SkipList skipList = new SkipList();
skipList.insert(1);
skipList.insert(3);
skipList.insert(5);
skipList.insert(2);
skipList.insert(4);
skipList.insert(7);
skipList.insert(6);
System.out.println(skipList.search(5).data);
skipList.delete(5);
skipList.delete(3);
skipList.delete(2);
System.out.println(skipList.search(3)==null);
System.out.println(skipList.search(5)==null);
System.out.println(skipList.search(2)==null);
System.out.println(skipList.search(1)==null);
System.out.println(skipList.search(6).data);
skipList.printList();
}
}
参考:https://mp.weixin.qq.com/s/Ok0laJMn4_OzL-LxPTHawQ,对其删除操作做了一定的优化,对其增加层次的操作做了限制。