zoukankan      html  css  js  c++  java
  • 跳表

    概述

    线性表中的链表是我们都很熟悉的结构了, 链表的增删优于数组, 但是不支持随机访问, 链表在查找时, 只能从头节点向后遍历, 那么针对链表, 能不能解决其访问效率的问题呢? 跳表来了, 顾名思义, 跳表就是可以跳跃的表, 我简单画了张图: 

    在原来链表的基础上, 建立一个新的索引链表, 原链表没两个建立一个

    原来查找节点5的访问顺序是: 1->2->3->4->5->6, 共遍历了6个节点

    现在在索引的基础上查找5的访问顺序是: 1->3->5->5->6(先访问索引), 共遍历了5个节点

    这种链表加索引的结构就是跳表

    查找

    从刚才的介绍中可以看出, 加了一层索引后, 访问效率变高了, 那么再加一层呢? 

    我们再次访问节点6, 访问顺序是: 1->5->5->5->6, 需要访问的节点又变少了, 原来访问节点6需要遍历6次, 现在只需要遍历5次

    什么, 效率提升不明显? 好, 我加大数据量你再看: 

    图画的有些简陋, 将就看吧. 原来链表访问节点128需要遍历128次, 现在只需要遍历14次就可以, 很明显的看出, 跳表确实可以提高查询效率

    时间复杂度

    在一个链表种, 查询时间复杂度是O(n)

    那么, 添加了索引之后, 跳表的查询时间复杂度能优化多少呢? 从上面的例子可以看出, 简直就是二分查找的翻版, 时间复杂度O(logn)

    空间复杂度

    很清楚的看出来, 跳表的解决方案就是用空间来换时间

    若原来的链表占用空间为n, 那么一级索引占用空间为n/2, 二级索引占用空间为n/4

    总占用空间=n+n/2+n/4+...+2=2n-2

    所以, 其空间复杂度为O(n)

    插入和删除

    当链表有了高效的查找时, 高效的删除和插入也就是顺理成章的事了. 

    先别高兴太早, 当我们对链表的数据进行插入和删除操作时, 一个因为建立索引而带来的新问题出现了, 当更新链表时, 也要更新索引. 当我们在两个节点之间频繁更新数据时, 就会导致这一段数据过多, 索引就减少了他的意义, 甚至极端情况会退化为单链表. 

    那么如何保证跳表的平衡, 避免跳表因为插入而出现复杂度退化呢? 

    一种解决方案是, 当链表插入新的数据时, 同时将新插入的数据添加到跳表的索引中, 这样就解决了索引的问题, 但是将节点更新到所有索引中显然不可取, 同时也会降低查询的效率, 针对这种情况, 通过一个随机函数, 比如: 链表共又3级索引, 随机数是2, 那么就将新插入的节点添加到第一、二级索引中, 如下图: 


    以上, 就是跳表的简单介绍!!

  • 相关阅读:
    [Linux Sets] hosts, wlan and other net-rele
    [Source] 温柔的图片
    [CATARC_2017] 第三周 & 残四周
    [CATARC_2017] 第二周
    ubuntu 安装
    知规矩者混天下言。
    python+selenium的web自动化测试之二(Jenkins自动执行)
    python+selenium的web自动化测试之一(手工执行)
    Python 入门小实例笔记
    Web安全测试工具 Burp Suit 使用简介
  • 原文地址:https://www.cnblogs.com/hujingnb/p/10854180.html
Copyright © 2011-2022 走看看