跳跃表实现与原理
来源:互联网 发布:淘宝打单插件 编辑:程序博客网 时间:2024/05/20 19:48
/**
* 跳表节点数据存储结构 */ class SkipNode<E extends Comparable<? super E>> { public final E value; //节点存储的数据 public final SkipNode<E>[] forward; //节点的指针数组 /** * 根据节点的层级构造一个节点 * @param level 节点层级 * @param value 节点存储值 */ @SuppressWarnings("unchecked") public SkipNode(int level, E value) { forward = new SkipNode[level + 1];//level层的元素后面带着level+1的指针数组 this.value = value; } } public class SkipSet<E extends Comparable<? super E>> { /** * 概率因子,实验证明p=1/e比p=0.5要好,e是个神奇的数字! */ // public static final double P = 0.5; public static final double P = 1/Math.E; /** * 最大层级 */ public static final int MAX_LEVEL = 6; /** * 开始节点,不存值,贯穿所有层 */ public final SkipNode<E> header = new SkipNode<E>(MAX_LEVEL, null); /** * 当前跳表的最高层级 */ public int level = 0; /** * 插入一个元素 * @param value 待插入值 */ @SuppressWarnings("unchecked") public void insert(E value) { SkipNode<E> x = header; SkipNode<E>[] update = new SkipNode[MAX_LEVEL + 1]; //查找元素的位置,这里其实做了一次contain操作,注释见contain for (int i = level; i >= 0; i--) { while (x.forward[i] != null && x.forward[i].value.compareTo(value) < 0) { x = x.forward[i]; } //update[i]是比value小的数里面最大的,是value的前置节点 update[i] = x; } x = x.forward[0]; //此处不允许插入相同元素,为一个set if (x == null || !x.value.equals(value)) {//跳表中不包含所要插的元素 //随机产生插入的层级 int lvl = randomLevel(); //产生的随机层级比当前跳表的最高层级大,需要添加相应的层级,并更新最高层级 if (lvl > level) { for (int i = level + 1; i <= lvl; i++) { update[i] = header; } level = lvl; } //生成新节点 x = new SkipNode<E>(lvl, value); //调整节点的指针,和指向它的指针 for (int i = 0; i <= lvl; i++) { x.forward[i] = update[i].forward[i]; update[i].forward[i] = x; } } } /** * 删除一个元素 * @param value 待删除值 */ @SuppressWarnings("unchecked") public void delete(E value) { SkipNode<E> x = header; SkipNode<E>[] update = new SkipNode[MAX_LEVEL + 1]; //查找元素的位置,这里其实做了一次contain操作,注释见contain for (int i = level; i >= 0; i--) { while (x.forward[i] != null && x.forward[i].value.compareTo(value) < 0) { x = x.forward[i]; } update[i] = x; } x = x.forward[0]; //删除元素,调整指针 if (x.value.equals(value)) { for (int i = 0; i <= level; i++) { if (update[i].forward[i] != x) break; update[i].forward[i] = x.forward[i]; } //如果元素为本层最后一个元素,则删除同时降低当前层级 while (level > 0 && header.forward[level] == null) { level--; } } } /** * 查找是否包含此元素 * @param searchValue 带查找值 * @return true:包含;false:不包含 */ public boolean contains(E searchValue) { SkipNode<E> x = header; //从开始节点的最高层级开始查找 for (int i = level; i >= 0; i--) { //当到达本层级的NULL节点或者遇到比查找值大的节点时,转到下一层级查找 while (x.forward[i] != null && x.forward[i].value.compareTo(searchValue) < 0) { x = x.forward[i]; } } x = x.forward[0]; //此时x有三种可能,1.x=null,2.x.value=searchValue,3.x.value>searchValue return x != null && x.value.equals(searchValue); } /** * 这里是跳表的精髓所在,通过随机概率来判断节点的层级 * @return 节点的层级 */ public static int randomLevel() { int lvl = (int) (Math.log(1. - Math.random()) / Math.log(1. - P)); return Math.min(lvl, MAX_LEVEL); } /** * 输出跳表的所有元素 * 遍历最底层的元素即可 */ public String toString() { StringBuilder sb = new StringBuilder(); sb.append("{"); SkipNode<E> x = header.forward[0]; while (x != null) { sb.append(x.value); x = x.forward[0]; if (x != null) sb.append(","); } sb.append("}"); return sb.toString(); } }
以上是跳跃表在java里的实现
阅读全文
0 0
- 跳跃表实现与原理
- 跳跃表实现的原理
- 跳跃表实现的原理
- 跳跃表实现的原理
- Skip List(跳跃表)原理详解与实现
- Skip List(跳跃表)原理详解与实现
- Skip List(跳跃表)原理详解与实现
- Skip List(跳跃表)原理详解与实现
- Skip List(跳跃表)原理详解与实现
- Skip List(跳跃表)原理详解与实现
- Skip List(跳跃表)原理详解与实现
- Skip List(跳跃表)原理详解与实现
- Skip List(跳跃表)原理详解与实现
- 跳跃表-原理及Java实现
- 跳跃表 SkipList【数据结构】原理及实现
- 跳跃表-原理及Java实现
- 【转】跳跃表-原理及Java实现
- 跳跃表的原理及实现
- MongoDB数据库索引
- 三、变量:shell变量的定义、使用、重命名、只读变量、删除变量、变量类型、特殊变量
- c语言的关键字
- Spring and AOP
- 使用Masonry设置自适应高度的UITableviewHeadView
- 跳跃表实现与原理
- BP算法
- WebService入门
- POJ 1011 Sticks(DFS+剪枝)详细注释
- POJ
- String.format()
- CentOS6.5 安装Apache
- Android 调试时,如何查找手机Activity在项目中对应的源码
- c++学习-static_cast、dynamic_cast、const_cast和reinterpret_cast总结