当前位置: 首页 > news >正文

资讯门户网站无锡市建设局一号通网站

资讯门户网站,无锡市建设局一号通网站,app科技产品网站建设,网站搜索引擎优化报告文章目录 什么是跳表跳表的时间复杂度跳表的空间复杂度如何高效的插入和删除跳表索引动态更新代码示例 什么是跳表 对于一个单链表来讲#xff0c;即便链表中存储的数据是有序的#xff0c;如果我们要想在其中查找某个数据#xff0c;也只能从头到尾遍历链表。这样查找效率… 文章目录 什么是跳表跳表的时间复杂度跳表的空间复杂度如何高效的插入和删除跳表索引动态更新代码示例 什么是跳表 对于一个单链表来讲即便链表中存储的数据是有序的如果我们要想在其中查找某个数据也只能从头到尾遍历链表。这样查找效率就会很低时间复杂度会很高是 O(n)。 那怎么来提高查找效率呢如果像图中那样对链表建立一级“索引”查找起来是不是就会更快一些呢每两个结点提取一个结点到上一级我们把抽出来的那一级叫做索引或索引层。你可以看我画的图。图中的 down 表示 down 指针指向下一级结点。 如果我们现在要查找某个结点比如 16。我们可以先在索引层遍历当遍历到索引层中值为 13 的结点时我们发现下一个结点是 17那要查找的结点 16 肯定就在这两个结点之间。然后我们通过索引层结点的 down 指针下降到原始链表这一层继续遍历。这个时候我们只需要再遍历 2 个结点就可以找到值等于 16 的这个结点了。这样原来如果要查找 16需要遍历 10 个结点现在只需要遍历 7 个结点。 从这个例子里我们看出加来一层索引之后查找一个结点需要遍历的结点个数减少了也就是说查找效率提高了。那如果我们再加一级索引呢效率会不会提升更多呢 跟前面建立第一级索引的方式相似我们在第一级索引的基础之上每两个结点就抽出一个结点到第二级索引。现在我们再来查找 16只需要遍历 6 个结点了需要遍历的结点数量又减少了。 这种链表加多级索引的结构就是跳表。 跳表的时间复杂度 按照我们刚才讲的每两个结点会抽出一个结点作为上一级索引的结点那第一级索引的结点个数大约就是 n/2第二级索引的结点个数大约就是 n/4第三级索引的结点个数大约就是 n/8依次类推也就是说第 k 级索引的结点个数是第 k-1 级索引的结点个数的 1/2那第 k 级索引结点的个数就是 n/(2k)。 假设索引有 h 级最高级的索引有 2 个结点。通过上面的公式我们可以得到 n/(2h)2从而求得 hlog2n-1。如果包含原始链表这一层整个跳表的高度就是 log2n。我们在跳表中查询某个数据的时候如果每一层都要遍历 m 个结点那在跳表中查询一个数据的时间复杂度就是 O(m*logn)。 那这个 m 的值是多少呢按照前面这种索引结构我们每一级索引都最多只需要遍历 3 个结点也就是说 m3为什么是 3 呢我来解释一下。 假设我们要查找的数据是 x在第 k 级索引中我们遍历到 y 结点之后发现 x 大于 y小于后面的结点 z所以我们通过 y 的 down 指针从第 k 级索引下降到第 k-1 级索引。在第 k-1 级索引中y 和 z 之间只有 3 个结点包含 y 和 z所以我们在 K-1 级索引中最多只需要遍历 3 个结点依次类推每一级索引都最多只需要遍历 3 个结点。 通过上面的分析我们得到 m3所以在跳表中查询任意数据的时间复杂度就是 O(logn)。这个查找的时间复杂度跟二分查找是一样的。换句话说我们其实是基于单链表实现了二分查找. 跳表的空间复杂度 通过上面的分析我们得到 m3所以在跳表中查询任意数据的时间复杂度就是 O(logn)。这个查找的时间复杂度跟二分查找是一样的。换句话说我们其实是基于单链表实现了二分查找 这几级索引的结点总和就是 n/2n/4n/8…842n-2。所以跳表的空间复杂度是 O(n)。也就是说如果将包含 n 个结点的单链表构造成跳表我们需要额外再用接近 n 个结点的存储空间。 如何高效的插入和删除 我们知道在单链表中一旦定位好要插入的位置插入结点的时间复杂度是很低的就是 O(1)。但是这里为了保证原始链表中数据的有序性我们需要先找到要插入的位置这个查找操作就会比较耗时。 对于纯粹的单链表需要遍历每个结点来找到插入的位置。但是对于跳表来说我们讲过查找某个结点的时间复杂度是 O(logn)所以这里查找某个数据应该插入的位置方法也是类似的时间复杂度也是 O(logn)。我画了一张图你可以很清晰地看到插入的过程。 我们再看下删除操作。 如果这个结点在索引中也有出现我们除了要删除原始链表中的结点还要删除索引中的。因为单链表中的删除操作需要拿到要删除结点的前驱结点然后通过指针操作完成删除。所以在查找要删除的结点的时候一定要获取前驱结点。当然如果我们用的是双向链表就不需要考虑这个问题了。 跳表索引动态更新 当我们不停地往跳表中插入数据时如果我们不更新索引就有可能出现某 2 个索引结点之间数据非常多的情况。极端情况下跳表还会退化成单链表。 作为一种动态数据结构我们需要某种手段来维护索引与原始链表大小之间的平衡也就是说如果链表中结点多了索引结点就相应地增加一些避免复杂度退化以及查找、插入、删除操作性能下降。 当我们往跳表中插入数据的时候我们可以选择同时将这个数据插入到部分索引层中。如何选择加入哪些索引层呢 我们通过一个随机函数来决定将这个结点插入到哪几级索引中比如随机函数生成了值 K那我们就将这个结点添加到第一级到第 K 级这 K 级索引中。 随机函数的选择很有讲究从概率上来讲能够保证跳表的索引大小和数据大小平衡性不至于性能过度退化。 代码示例 public class SkipList {private static final float SKIPLIST_P 0.5f;private static final int MAX_LEVEL 16;private int levelCount 1;private Node head new Node(); // 带头链表public Node find(int value) {Node p head;for (int i levelCount - 1; i 0; --i) {while (p.forwards[i] ! null p.forwards[i].data value) {p p.forwards[i];}}if (p.forwards[0] ! null p.forwards[0].data value) {return p.forwards[0];} else {return null;}}public void insert(int value) {// 随机索引层数int level randomLevel();// 定义新节点Node newNode new Node();newNode.data value;//Node update[] new Node[level];for (int i 0; i level; i) {update[i] head;}// record every level largest value which smaller than insert value in update[]Node p head;for (int i level - 1; i 0; --i) {while (p.forwards[i] ! null p.forwards[i].data value) {p p.forwards[i];}update[i] p;// use update save node in search path}// in search path node next node become new node forwords(next)for (int i 0; i level; i) {newNode.forwards[i] update[i].forwards[i];update[i].forwards[i] newNode;}// update node hightif (levelCount level) levelCount level;}public void delete(int value) {Node[] update new Node[levelCount];Node p head;for (int i levelCount - 1; i 0; --i) {while (p.forwards[i] ! null p.forwards[i].data value) {p p.forwards[i];}update[i] p;}if (p.forwards[0] ! null p.forwards[0].data value) {for (int i levelCount - 1; i 0; --i) {if (update[i].forwards[i] ! null update[i].forwards[i].data value) {update[i].forwards[i] update[i].forwards[i].forwards[i];}}}while (levelCount 1 head.forwards[levelCount] null) {levelCount--;}}// 理论来讲一级索引中元素个数应该占原始数据的 50%二级索引中元素个数占 25%三级索引12.5% 一直到最顶层。// 因为这里每一层的晋升概率是 50%。对于每一个新插入的节点都需要调用 randomLevel 生成一个合理的层数。// 该 randomLevel 方法会随机生成 1~MAX_LEVEL 之间的数且 // 50%的概率返回 1// 25%的概率返回 2// 12.5%的概率返回 3 ...private int randomLevel() {int level 1;while (Math.random() SKIPLIST_P level MAX_LEVEL)level 1;return level;}public void printAll() {Node p head;while (p.forwards[0] ! null) {System.out.print(p.forwards[0] );p p.forwards[0];}System.out.println();}public class Node {private int data -1;private Node forwards[] new Node[MAX_LEVEL];} }
http://www.w-s-a.com/news/890615/

相关文章:

  • 织梦做商城网站企业网络建站
  • 网站后期维护都有什么wordpress首页加图片
  • 展会网站怎么做网页设计与制作教程版徐洪亮课后答案
  • 石景山网站建设设计公司建设网站怎么建立服务器
  • 本地生活服务平台app网站关键词优化原理
  • 建网站的公司叫什么重庆论坛建站模板
  • 湖北网站制作公司银川网站建设哪家不错
  • 网站后台演示地址服装网站建设公司推荐
  • 湖北钟祥建设局网站旅游哪个网站最好
  • 浙江建设工程信息网站辽宁建设工程信息网场内业绩什么意思
  • 郑州做网站公司 汉狮网络专业图片搜集网站怎么做
  • 网站托管是什么品牌推广营销平台
  • 制作网站的难度贵州省兴义市建设局网站
  • 永春建设局网站室内设计师培训班学费多少
  • 做仿站如何获取网站源码windows2012做网站
  • 网站建设最好的公司东莞外贸网站
  • 普兰店网站建设一般做网站什么价格
  • 网站建设的发展目标甘肃网站设计公司
  • 常州西站建设规划室内装修设计学校哪里好
  • 大连网站制作选择ls15227如何编辑网站
  • 网站发稿平台迪士尼网站是谁做的
  • 常州有哪些好的网站建设案例wordpress 360 插件
  • 模板网站有后台么柳城网站建设
  • 地方门户网站制作一级做c爱片的网站
  • 自己上传图片做动漫图网站北京福田汽车
  • 一级a做爰片免费网站录像ps做网站图片水印
  • 网页广告投放成都优化推广公司
  • 网站开发 印花税网页制作站点
  • 创建个人网站有什么好处国外建站系统
  • 桂林学校网站制作2018年网站设计公司