• 数据结构与算法之美学习笔记:第十七讲


    一、课前思考

    两节我们讲了二分查找算法。当时我讲到,因为二分查找底层依赖的是数组随机访问的特性,所以只能用数组来实现。如果数据存储在链表中,就真的没法用二分查找算法了吗?

    实际上,我们只需要对链表稍加改造,就可以支持类似“二分”的查找算法。我们把改造之后的数据结构叫作跳表(Skiplist),也就是今天要讲的内容。

    跳表这种数据结构对你来说,可能会比较陌生,因为一般的数据结构和算法书籍里都不怎么会讲。但是它确实是一种各方面性能都比较优秀的动态数据结构,可以支持快速的插入、删除、查找操作,
    写起来也不复杂,甚至可以替代红黑树(Red-blacktree)。

    Redis中的有序集合(Sorted Set)就是⽤跳表来实现的。如果你有一定基础,应该知道红黑树也可以实现快速的插入、删除和查找操作。那Redis为什么会选择用跳表来实现有序集合呢?
     为什么不用红黑树呢?学完今天的内容,你就知道答案了。

    二、如何理解跳表

    1、单链表

    2、怎么提高查询效率

    1、18个节点一级索引

    2、18个节点二级索引

    3、64个节点建立五级索引

    3、当链表的⻓度n⽐较⼤时

    三、用跳表查询到底有多快

    1、如果链表⾥有n个结点,会有多少级索引?

    2、复杂度推算过程

    3、M值为什么是3

    4、基于单链表实现二分查找

    四、跳表是不是很浪费内存

    1、索引节点数是一个等比数列

    2、通过等⽐数列求和公式

    3、实际上,在软件开发中,我们不必太在意索引占⽤的额外空间

    五、高效的动态插入删除

    1、在跳表单链表中插⼊⼀个数据的时间复杂度

    2、在跳表中删除⼀个数据的时间复杂度

    六、跳表索引动态更新

    1、如果链表中结点多了,索引结点就相应地增加⼀些

    2、跳表是通过随机函数来维护前⾯提到的“平衡性”

    3、如何选择加⼊哪些索引层呢?

    七、解答开篇

    1、如果你去查看Redis的开发⼿册,就会发现Redis中的有序集合⽀持的核⼼操作主要有下⾯这⼏个

    1、插⼊⼀个数据;删除⼀个数据;查找⼀个数据;

    2、按照区间查找数据(⽐如查找值在[100, 356]之间的数据

    3、迭代输出有序序列。

    2、Redis之所以⽤跳表来实现有序集合,还有其他原因

    3、跳表也不能完全替代红⿊树

    跳表的实现还是稍微有点复杂的,我将Java实现的代码放到了GitHub中,你可以根据我刚刚的讲解,对照着代码仔细思考⼀下。你不⽤死记硬背代码,跳表的实现并不是我们这节的重点

    八、内容小结

    今天我们讲了跳表这种数据结构。跳表使用空间换时间的设计思路,通过构建多级索引来提高查询的效率,实现了基于链表的“二分查找”。跳表是一种动态数据结构,支持快速的插入、删除、查找操作,时间复杂度都是O(logn)。

    跳表的空间复杂度是O(n)。不过,跳表的实现非常灵活,可以通过改变索引构建策略,有效平衡执行效率和内存消耗。虽然跳表的代码实现并不简单,但是作为一种动态数据结构,比起红黑树来说,
    实现要简单多了。所以很多时候,我们为了代码的简单、易读,比起红黑树,我们更倾向用跳表。

    九、课后思考

    在今天的内容中,对于跳表的时间复杂度分析,我分析了每两个结点提取一个结点作为索引的时间复杂度。如果每三个或者五个结点提取一个结点作为上级索引,
    对应的在跳表中查询数据的时间复杂度是多少呢

    经典留言escray

    如果每三个或者五个节点提取一个节点作为上级索引,那么对应的查询数据时间复杂度,应该也还是 O(logn)。

    假设每 5 个节点提取,那么最高一层有 5 个节点,而跳表高度为 log5n,每层最多需要查找 5 个节点,即 O(mlogn) 中的 m = 5,最终,时间复杂度为 O(logn)。
    空间复杂度也还是 O(logn),虽然省去了一部分索引节点,但是似乎意义不大。

    不知道在一般的生产系统,跳表的提取是按照多少个节点来实现?还是每个系统根据实际情况,都不一样。
    看了跳表的 Java 实现,查找部分的代码真是漂亮,插入部分看了半天才看明白。

  • 相关阅读:
    javascript事件中'return false'详解
    jquery源码——noConflict实现
    Charles抓包工具安装与配置
    js模版引擎开发实战以及对eval函数的改进
    CSS元素垂直居中方法总结
    你必须要了解的几种排序方法
    学习Redux之分析Redux核心代码分析
    React中使用CSSTransitionGroup插件实现轮播图
    在React中使用CSS Modules设置样式
    React虚拟DOM具体实现——利用节点json描述还原dom结构
  • 原文地址:https://www.cnblogs.com/luoahong/p/11864974.html
Copyright © 2020-2023  润新知