跳表的java实现
节点的定义
/**
* 跳表节点定义
*/
@Data
@AllArgsConstructor
public class SkipNode<T> {
int key;
T val;
SkipNode next, down;
public SkipNode(int key, T val) {
this.key = key;
this.val = val;
}
}
跳表
public class SkipList {
SkipNode head;
//支持的最大层数
public static final int MAX_LEVEL = 10;
int highLevel;//当前队列的最大层数
public SkipList(){
head = new SkipNode<>(Integer.MIN_VALUE,null);
highLevel = 0;
}
/**
* 返回随机层数
*/
public int getRandomLevel()
{
int lev = 1;
while(RandomUtil.randomInt()%2==0 &&lev< MAX_LEVEL )
{
lev++;
}
return lev;
}
/**
* 查询节点是否存在,存在则返回节点
* 思路:能往右走就往右走,不能就往下
*/
public SkipNode search(int key)
{
SkipNode tar = head;
while(tar!=null)
{
if(tar.getKey()==key)
{
break;
}
if(tar.next==null) tar = tar.down;
else if(tar.next.getKey()>key) tar = tar.down;
else tar = tar.next;
}
return tar;
}
/**
* 查询key的值
*/
public Object get(int key)
{
SkipNode tar = head;
while(tar!=null)
{
if(tar.getKey()==key)
{
break;
}
if(tar.next==null) tar = tar.down;
else if(tar.next.getKey()>key) tar = tar.down;
else tar = tar.next;
}
if(tar!=null) return tar.getVal();
else return null;
}
/**
* 插入
* 思路:先判断 节点是否存在,不存在就生成随机高度,然后找到每一层的前驱节点
* 因为每一个节点都需要有个往下的节点,所以要从下往上插入
*/
public void put(int key, Object val)
{
SkipNode tmp = head;
//之后要找到 新节点在每一层的前驱节点,然后由下而上地新增
List<SkipNode> pre = new ArrayList<>();
//判断key是否已经存在
SkipNode tar =search(key) ;
if(tar!=null)
{
//存在,则将该节点所有层都刷新val
while(tar!=null)
{
tar.setVal(val);
tar = tar.down;
}
return;
}
int lev = getRandomLevel();//随机生成
System.out.println("当前key为 "+key + ",当前节点层数 "+lev);
//如果当前lev 是整个跳表最高值,那么头节点也要增加层数
for(int i=highLevel+1;i<=lev;i++)
{
tmp = new SkipNode<>(Integer.MIN_VALUE,null);
tmp.next = null;
tmp.down = head;
head = tmp;
}
highLevel = Math.max(lev,highLevel);
tmp = head;
int cnt = highLevel;
//要找到对应层数的开始节点
while(cnt!=lev)
{
tmp = tmp.down;
cnt--;
}
//寻找前驱节点
while(tmp!=null)
{
if(tmp.getKey() ==key)
{
tmp.setVal(val);
tmp = tmp.down;
}
else if(tmp.next==null)
{
//因为list实际上存的是引用,所以要复制一份再存进去
SkipNode x = tmp;
pre.add(x);
tmp = tmp.down;
}
else if(tmp.next.getKey()>key)
{
SkipNode x = tmp;
pre.add(x);
tmp = tmp.down;
}
else {
tmp = tmp.next;
}
}
//由下而上新增节点
SkipNode down = null;
for(int i=pre.size()-1;i>=0;i--)
{
SkipNode node = new SkipNode<>(key,val);
node.down = down;
pre.get(i).next = node;
down = node;
}
}
public void delete(int key)
{
SkipNode tmp = head;
while(tmp!=null)
{
if(tmp.next==null) tmp = tmp.down;
else if(tmp.next.getKey()==key)
{
tmp.next = tmp.next.next;
tmp = tmp.down;
}
else if(tmp.next.getKey()<key) tmp = tmp.next;
else tmp = tmp.down;
}
}
public void print()
{
SkipNode tmp = head;
while(tmp!=null)
{
SkipNode now = tmp;
while(now!=null)
{
System.out.print("["+now.getKey()+" "+now.getVal()+"]");
System.out.print(" ");
now = now.next;
}
System.out.println();
tmp = tmp.down;
}
}
public static void main(String[] args) {
SkipList skipList = new SkipList();
skipList.put(1,10);
skipList.put(1,11);
skipList.put(2,12);
skipList.put(3,11);
skipList.put(3,15);
skipList.put(4,14);
skipList.delete(1);
System.out.println(skipList.get(3));
skipList.print();
}
}