跳表的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;
}
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<>();
SkipNode tar =search(key) ;
if(tar!=null)
{
while(tar!=null)
{
tar.setVal(val);
tar = tar.down;
}
return;
}
int lev = getRandomLevel();
System.out.println("当前key为 "+key + ",当前节点层数 "+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)
{
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();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)