java冒险 跳跃_java实现跳跃表

packagecom.ljd.skiplist;importjava.util.ArrayList;importjava.util.List;importjava.util.Random;/*** Created by author on 2017/10/9.

* 实现跳跃表:能够对递增链表实现logN的查询时间*/

public class SkipList{public static voidmain(String[] args) {//测试随机数生成的结果对二取模,结果是否是接近于0.5//Random r = new Random(47);//int t = 1, a = 1;//while (a < 10000000) {//a++;//if (r.nextInt() % 2 == 0)//t++;//}//System.out.println(t * 1.0 / a);

SkipList list = new SkipList<>();

list.put(1.0, "1.0");

System.out.println(list);

list.put(2.0, "2.0");

System.out.println(list);

list.put(3.0, "3.0");

System.out.println(list);

list.put(4.0, "4.0");

System.out.println(list);

list.put(4.0, "5.0");

System.out.println(list);

list.delete(3.0);

list.delete(3.5);

System.out.println(list);

System.out.println("查找4.0" + list.get(4.0));

}/*** 跳跃表的节点的构成

*

*@param*/

private static class SkipNode{

E val;//存储的数据

double score;//跳跃表按照这个分数值进行从小到大排序。

SkipNode next, down;//next指针,指向下一层的指针

SkipNode() {

}

SkipNode(E val,doublescore) {this.val =val;this.score =score;

}

}private static final int MAX_LEVEL = 1 << 6;//跳跃表数据结构

private SkipNodetop;private int level = 0;//用于产生随机数的Random对象

private Random random = newRandom();publicSkipList() {//创建默认初始高度的跳跃表

this(4);

}//跳跃表的初始化

public SkipList(intlevel) {this.level =level;int i =level;

SkipNode temp = null;

SkipNode prev = null;while (i-- != 0) {

temp= new SkipNode(null, Double.MIN_VALUE);

temp.down=prev;

prev=temp;

}

top= temp;//头节点

}/*** 产生节点的高度。使用抛硬币

*

*@return

*/

private intgetRandomLevel() {int lev = 1;while (random.nextInt() % 2 == 0)

lev++;return lev > MAX_LEVEL ?MAX_LEVEL : lev;

}/*** 查找跳跃表中的一个值

*

*@paramscore

*@return

*/

public T get(doublescore) {

SkipNode t =top;while (t != null) {if (t.score ==score)returnt.val;if (t.next == null) {if (t.down != null) {

t=t.down;continue;

}else

return null;

}if (t.next.score >score) {

t=t.down;

}elset=t.next;

}return null;

}public void put(doublescore, T val) {//1,找到需要插入的位置

SkipNode t = top, cur = null;//若cur不为空,表示当前score值的节点存在

List> path = new ArrayList<>();//记录每一层当前节点的前驱节点

while (t != null) {if (t.score ==score) {

cur=t;break;//表示存在该值的点,表示需要更新该节点

}if (t.next == null) {

path.add(t);//需要向下查找,先记录该节点

if (t.down != null) {

t=t.down;continue;

}else{break;

}

}if (t.next.score >score) {

path.add(t);//需要向下查找,先记录该节点

if (t.down == null) {break;

}

t=t.down;

}elset=t.next;

}if (cur != null) {while (cur != null) {

cur.val=val;

cur=cur.down;

}

}else {//当前表中不存在score值的节点,需要从下到上插入

int lev =getRandomLevel();if (lev > level) {//需要更新top这一列的节点数量,同时需要在path中增加这些新的首节点

SkipNode temp = null;

SkipNode prev = top;//前驱节点现在是top了

while (level++ !=lev) {

temp= new SkipNode(null, Double.MIN_VALUE);

path.add(0, temp);//加到path的首部

temp.down =prev;

prev=temp;

}

top= temp;//头节点

level = lev;//level长度增加到新的长度

}//从后向前遍历path中的每一个节点,在其后面增加一个新的节点

SkipNode downTemp = null, temp = null, prev = null;//System.out.println("当前深度为"+level+",当前path长度为"+path.size());

for (int i = level - 1; i >= level - lev; i--) {

temp= new SkipNode(val, score);

prev=path.get(i);

temp.next=prev.next;

prev.next=temp;

temp.down=downTemp;

downTemp=temp;

}

}

}/*** 根据score的值来删除节点。

*

*@paramscore*/

public void delete(doublescore) {//1,查找到节点列的第一个节点的前驱

SkipNode t =top;while (t != null) {if (t.next == null) {

t=t.down;continue;

}if (t.next.score ==score) {

// 在这里说明找到了该删除的节点          t.next = t.next.next;

t = t.down;

//删除当前节点后,还需要继续查找之后需要删除的节点

continue;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值