跳表代码如下:
/**
* 跳表:
*
* 下面实现一个跳表
*/
public class SimpleSkipList {
//每一层头部节点的标记符
private static final byte HEAD_BIT = (byte) -1;
//每一层尾部节点的标记符
private static final byte TAIL_BIT = (byte) 1;
//每一个数据节点的标记符
private static final byte DATA_BIT = (byte) 0;
//头节点
private Node head;
//尾部节点
private Node tail;
//元素个数
private int size;
//调表层高
private int height;
//随机数,主要用于通过随机的方式决定元素应该被放在第几层
private Random random;
//初始化,在空的跳表中只有2个元素,头节点和尾节点
public SimpleSkipList(){
this.head = new Node(null,HEAD_BIT);
this.tail = new Node(null,TAIL_BIT);
//初始化时,头部节点的右边是尾部节点,尾部节点的左边元素是头部节点
this.head.right = this.tail;
this.tail.left = this.head;
this.random = new Random(System.currentTimeMillis());
}
/**
* 查找,从最高层head 节点开始查找
* @param data
* @return
*/
public Node find(Integer data){
//从头节点开始查找
Node current = head;
for(;;){
while (current.right.bit != TAIL_BIT && current.right.value <= data){
//要查找的数据可能在这一层,继续往右遍历
current = current.right;
}
//当 data不在这一层,那可能在下一层
//当current 存在down 节点,则进入到下一层
if(current.down != null){
current = current.down;
}else {
//到达最低层,终止循环
break;
}
}
return current;
}
/**
* todo 核心方法
* 新增
*
* @param data
*/
public void add(Integer data){
//根据data 找到他的存储位置,也就是临近节点,需要注意的是,此刻该节点在
//整个跳表的第一层
Node nearNode = this.find(data);
//定义新节点
Node newNode = new Node(data);
//新节点的左节点为nearNode
newNode.left = nearNode;
//新节点的右节点为 nearNode.right,相当于将新节点插入到了 nearNode 和 nearNode.right 之间
newNode.right = nearNode.right;
//
nearNode.right.left = newNode;
//
nearNode.right = newNode;
//定义当前层级为0,表示是第一层
int currentLevel = 0;
//根据随机值判断是否将新的节点放到新的层级,在跳表算法描述中该动作被称为抛硬币
while (random.nextDouble() < 0.5d){
//如果 currentLevel 大于整个跳表的层高,则需要为链表多增加一层链表
if(currentLevel > height){
height++;
//定义新层高的head 和 tail
Node dumyHead = new Node(null,HEAD_BIT);
Node dumyTail = new Node(null,TAIL_BIT);
//指定新层高 head 和 tail 的关系
dumyHead.right = dumyTail;
dumyHead.down = head;
head.up = dumyHead;
dumyTail.left = dumyHead;
dumyTail.down = tail;
tail.up = dumyTail;
head = dumyHead;
tail = dumyTail;
}
//在新的一层中添加 data 的节点,同样要维护上下层之间的关系
while ((nearNode != null) && nearNode.up == null){
nearNode = nearNode.left;
}
nearNode = newNode.up;
Node upNode = new Node(data);
upNode.left = nearNode;
upNode.right = nearNode.right;
upNode.down = newNode;
nearNode.right.left = upNode;
newNode.right = upNode;
newNode.up = upNode;
newNode = upNode;
currentLevel++;
}
size++;
}
//节点类
private static class Node{
private Integer value;
/**
* 跳表的每个节点周围节点的引用,分别是 上、下、左、右
*/
private Node up,down,left,right;
//节点类型
private byte bit;
public Node(Integer value){
this(value,DATA_BIT);
}
public Node(Integer value,byte bit){
this.value = value;
this.bit = bit;
}
@Override
public String toString() {
return value + " bit: " + bit;
}
}
public int size(){
return this.size;
}
public boolean isEmpty(){
return size == 0;
}
public boolean contains(Integer data){
Node n = find(data);
return data.equals(n.value);
}
public Integer get(Integer data){
Node node = find(data);
return data.equals(node.value)?node.value:null;
}
}