博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
算法基础课六:二分查找和跳表
阅读量:3732 次
发布时间:2019-05-22

本文共 1864 字,大约阅读时间需要 6 分钟。

二分查找

  1. 针对有序数据的查找算法,每次与集合的中间值进行比较,大于中间值,递归在右边集合中查找,反之从左边集合中查找,直到查找到元素,或者查找区间被缩小到0;

  2. 二分查找,假设区间缩小到最后一个元素才找到,那么每次缩小区间1/2,所以总共缩小了 logn 次,所以时间复杂度就是 o( logn ),这是一个极其高效的时间复杂度;

  3. 简单的二分查找,有几个适用条件;

有序数据	没有重复数据	适用于数组存储结构,不适用于链表结构,因为链表进行下标随机访问,时间复杂度会达到 o(n)	不适合于频繁插入,删除数据的场景,因为要维护数组元素有序,涉及数据搬移,时间成本高	数据量太小,直接顺序查找就可以了	数据量太大,也不太适合二分查找,因为需要用数组存储,需要连续内存空间

二分查找的变形问题

  1. 如果二分查找的有序集合中,有重复数据时,就需要用到二分查找的变形;

  2. 查找第一个值等于给定值的元素;

与简单二分查找类似,只不过查找元素和 mid 元素对比完之后		如果大于或小于 mid,与之前逻辑一样		如果等于 mid,查看下 mid -1 是否等于查找元素,如果等于,继续在左边集合查找,如果不等于,mid 即为第一个等于		另外注意 mid = 0,即为所求
  1. 查找最后一个值等于给定值的元素;
与 2 类似,如果大于或小于 mid,与之前逻辑一样	如果等于 mid,查看下 mid + 1 是否等于查找元素,如果等于,继续在右边集合查找,如果不等于,mid 即为最后一个等于
  1. 查找第一个大于等于给定值的元素;
与 2 类似,如果大于 mid,与之前逻辑一样	如果小于 mid,查看下 mid -1 是否小于查找元素,如果确实小于,那么 mid 就为第一个大于给定值的元素,其他情况都继续			在左边集合查找	如果等于 mid,查看下 mid -1 是否等于查找元素,如果等于,继续在左边集合查找,如果不等于,mid 即为第一个等于
  1. 查找最后一个小于等于给定值的元素;
与 2 类似,如果 mid 大于给定值,继续左边集合查找	如果 mid 小于给定值,查看 mid + 1 是否大于给定值,如果大于,那么 mid 即为最后一个小于给定值的元素,其他情况继续		在右边集合查找	如果 mid 等于给定值,查看 mid +1 是否大于给定值,如果大于,那么 mid 即为一个等于给定值的元素,其他情况继续在有		右边集合查找
  1. 引申,对 ip 的归属地,进行定位,假设有 20万,ip 区间和归属地的对应关系;
可以将 20 万个 ip 区间的首地址取出,然后进行排序组成一个有序集合	排序可以使用基数排序,从后到前,每一位进行计数排序	然后查找第一个大于等于给定值的元素	得到该元素后,如果是等于,即使用该区间对应的归属地即可,否则取该元素上一个元素区间对应的归属地
  1. 等于给定值的查找,一般用二叉树,或者散列表,二分查找一般用于区间查找,即变形问题;

跳表

  1. 因为二分查找,只支持数组结构,对于链表结构,可以改造成跳表结构,提高查找效率;

  2. 在数据有序的链表数据上,每几个元素,提升一个元素组成索引层,就是跳表结构,查找时,先在索引层锁定范围,然后下降到下层节点查找数据;

  3. 索引层还可以再抽出节点,再建立一层索引,跳表查询的时间复杂度是 o( logn );

如果按照2个节点抽出一个节点,组成索引层,然后索引层,也按照2个节点抽出一个节点,如此组成多级索引	第 k 级索引有 n/2^k 个节点,假设要求最高层索引有两个节点,那么 n/2^k = 2,得到 k = logn -1	所以链表的高度,就是 logn	每层最多需要遍历 3 个节点,是因为每一级索引和下层元素,间隔只有三个元素,从2个元素开始,确定一个区间后,只需在下			层,每层遍历 3 个节点即可	所以总的时间复杂度,就是 o(3logn),即 o(logn)
  1. 跳表的空间复杂度是 O( n ),每层节点数是 n/2 + n/4 + … + 2 = o( n );

  2. 跳表的插入和删除操作,因为要保证跳表数据的有序性,因此首先要查找要插入元素的位置,时间复杂度是 o( logn ),单纯插入的时间复杂度是 o( 1 ),所以总的时间复杂度就是 o( logn );

  3. redis 中有序集合,就是用跳表实现的,因为 redis 常用的一个操作是,按照区间查找数据,这种操作在红黑树等有序结构中,实现比较复杂,而在跳表中,只需找到区间最小值,然后依次向后遍历即可,非常高效;

转载地址:http://lsfin.baihongyu.com/

你可能感兴趣的文章
蓝桥杯 20模1-4-数字9 在1至2019中,有多少个数的数位中包含数字9? 注意,有的数中的数位中包含多个9,这个数只算一次。例如,1999这个数包含数字9,在计算只是算一个数。
查看>>
蓝桥杯真题 18国1-换零钞 x星球的钞票的面额只有:100元,5元,2元,1元,共4种。 小明去x星旅游,他手里只有2张100元的x星币,太不方便,恰好路过x星银行就去换零钱。 小明有点强迫症,
查看>>
蓝桥杯真题 14校3-大小之差
查看>>
蓝桥杯真题 15校1-单词计数 输入一个字符串,求它包含多少个单词。单词间以一个或者多个空格分开。 第一个单词前,最后一个单词后也可能有0到多个空格。 比如:“ abc xyz“ 包含两个单
查看>>
蓝桥杯真题 14省2-切面条 一根高筋拉面,中间切一刀,可以得到2根面条。 如果先对折1次,中间切一刀,可以得到3根面条。 如果连续对折2次,中间切一刀,可以得到5根面条。 那么,连续对折10次,
查看>>
蓝桥杯 算法训练 - 整数平均值
查看>>
蓝桥杯真题 13省2-马虎的算式 小明是个急性子,上小学的时候经常把老师写在黑板上的题目抄错了。 有一次,老师出的题目是:36 x 495 = ? 他却给抄成了:396 x 45 = ? 但结果却
查看>>
蓝桥杯真题 13省3-第39级台阶 小明刚刚看完电影《第39级台阶》,离开电影院的时候,他数了数礼堂前的台阶数,恰好是39级! 站在台阶前,他突然又想着一个问题: 如果我每一步只能迈上1个或2个台
查看>>
蓝桥杯真题 15省Ca1-方程整数解 方程: a^2 + b^2 + c^2 = 1000 a2+b2+c2=1000 a^2 + b^2 + c^2 = 1000a2+b2+c2=1000 这个
查看>>
C语言中怎么表示派 -π
查看>>
蓝桥杯 基础训练—闰年判断
查看>>
蓝桥杯 基础训练—十六进制转八进制 输入的第一行为一个正整数n (1<=n<=10)。   接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度
查看>>
蓝桥杯 基础训练—数列排序  给定一个长度为n的数列,将这个数列按从小到大的顺序排列。1<=n<=200
查看>>
蓝桥杯 基础训练—数列特征 给出n个数,找出这n个数的最大值,最小值,和。
查看>>
蓝桥杯 基础训练—特殊的数字 153是一个非常特殊的数,它等于它的每位数字的立方和,即153=1*1*1+5*5*5+3*3*3。编程求所有满足这种条件的三位十进制数。
查看>>
蓝桥杯真题 13省Jb1-世纪末的星期 曾有邪教称1999年12月31日是世界末日。当然该谣言已经不攻自破。 还有人称今后的某个世纪末的12月31日,如果是星期一则会.... 有趣的是,任何一个世
查看>>
蓝桥杯真题 18省1-第几天 2000年的1月1日,是那一年的第1天。 那么,2000年的5月4日,是那一年的第几天?
查看>>
蓝桥杯 14校4-回文数字  观察数字:12321,123321 都有一个共同的特征,无论从左到右读还是从右向左读,都是相同的。这样的数字叫做:回文数字。   本题要求你找到一些5位或6位的十进制
查看>>
蓝桥杯真题 18省Ca1-分数 1/1 + 1/2 + 1/4 + 1/8 + 1/16 + .... 每项是前一项的一半,如果一共有20项, 求这个和是多少,结果用分数表示出来。 类似: 3/2
查看>>
蓝桥杯真题 15省Ca8-饮料 乐羊羊饮料厂正在举办一次促销优惠活动。乐羊羊C型饮料,凭3个瓶盖可以再换一瓶C型饮料,并且可以一直循环下去(但不允许暂借或赊账)。 请你计算一下,如果小明不浪费瓶盖,
查看>>