https://zhuanlan.zhihu.com/p/110202102

前几天面了头条深圳的暑期实习,在一面中和面试官讨论到了这样一个问题:

面试官抛出了一个很经典的考题:许多数据库为什么使用B+树作为索引结构,有什么好处?

我想当然地觉得B+树就是个平衡二叉查找树的升级版,既然后者的时间查询复杂度为  ,那B+树作为m叉树,自然就是 咯?

面试官:不对不对,你想想,虽然你可以认为一共只有log(m)n层,但是你每一层平均都要遍历m/2个节点才能确定往下面哪一个分支走呀,这和二叉树的O(1)判断走哪个分支可不一样,我记得最终算出来的复杂度是log n,blabla(很快我们就自觉避开了这个一看就很复杂的复杂度推导)

我:有道理诶。。于是面试完后到牛客发帖求助,很快,有一位牛油给了我这样一个参考思路,这里表示感谢:

层数log(m)n,每一层平均m/2,所以一共是(m/2) * log(m)n,由于m是常数,所以复杂度O(log n),即以2为底n的对数

这已经是个很详细的推导了,但是最后一步怎么变成log n的我总是想不明白

我觉得这个答案是不准确的,我自己再推了一遍:

首先前面的步骤略,得到复杂度为(m/2) * log(m)n,这里系数1/2不影响复杂度可以直接略掉,但是m是同时存在于系数和底数里的,不应该省略,也很容易看出,m的取值对复杂度是有影响的。那么m该取多少?这个复杂度平均情况下的界是多少?

对mlog(m)n,可以把m放到底数中去,也就是log(m的1/m次方)n。(这里利用了一条性质,系数m放到底数中时,相当于底数开m次方,可以用换底公式证明)

容易证明,当m->1时,m的1/m次方->1;当m->正无穷时,m的1/m次方->1,也就是底数的值并不是m的单调函数,而更接近于一个两头小中间大的图象。

可以证明,当m取3时,底数取最大值,复杂度取最小值,此时底数约为三次根号3,约等于1.44,而log(1.44)n > log n,因此log n并不是上界。

(证明:对n的1/n次方取对数,求导,易得单调区间和最值)

结论:理论上,B+树的查找时间复杂度为 log1.44(n)

为什么是理论上?因为我总觉得没那么简单。事实上,数据库查找占大头的是磁盘I/O,当我们读取同一层的几个相邻节点时,它们很可能处于同一个磁盘块中,我们只需要一次磁盘I/O就可以取到,而往下遍历时,往往需要取别的磁盘块(未经文献查证,纯属个人猜测)。也就是说,层数和每层节点的个数这两个因素,它们可能是不等权的。实际设计中很可能要考虑更多的因素。

B+树检索的时间复杂度相关推荐

  1. 树状结构 - 时间复杂度

    树状结构的算法题时间复杂度是相对比较难的 因为有两种情况,一种是普通遍历,另一种是分治算法 而如Leetcode109. Convert Sorted List to Binary Search Tr ...

  2. 用递归树求解递归算法时间复杂度

    文章内容.图片均来自极客时间. 递归代码复杂度分析起来比较麻烦.一般来说有两种分析方法:递推公式和递归树. 1 递推公式法 归并排序的递推公式是: merge_sort(p-r) = merge(me ...

  3. 如何用递归树求快速排序时间复杂度

    其实也就是点看算法导论的心得,感觉算法导论写的有点不详细的补充 快速排序 我的理解就是利用分治法 ,递归排序最后合并的排序,因为快速排序的最坏时间复杂度比较低所以快速被叫做快速排序如图 对于求快速排序 ...

  4. Trie树检索字符串

    #include <stdio.h> #include <stdlib.h> #include <string.h>typedef struct TrieNode_ ...

  5. 递归树求递归算法时间复杂度

    开篇前言:为什么写这篇文章?笔者目前在学习各种各样的算法,在这个过程中,频繁地碰到到递归思想和分治思想,惊讶于这两种的思想的伟大与奇妙的同时,经常要面对的一个问题就是,对于一个给定的递归算法或者用分治 ...

  6. 树的遍历查找-家谱树检索

    找家谱成员 输入若干行,每一行的第一个输入为家谱中的某成员,该行接着输入的信息为每个孩子姓名. 最后一行的输入为要求查找的二个家谱成员的关系. 要求,根据输入的家谱成员信息,建立二叉树家谱关系图,并输 ...

  7. Trie(前缀树/字典树)及其应用

    from:https://www.cnblogs.com/justinh/p/7716421.html Trie,又经常叫前缀树,字典树等等.它有很多变种,如后缀树,Radix Tree/Trie,P ...

  8. Trie树(字典树)详细知识点及其应用

    Trie,又经常叫前缀树,字典树等等.它有很多变种,如后缀树,Radix Tree/Trie,PATRICIA tree,以及bitwise版本的crit-bit tree.当然很多名字的意义其实有交 ...

  9. 阿里新突破!自主创新的下一代匹配推荐技术:任意深度学习+树状全库检索

    阿里妹导读:电商时代,消费者对推荐系统已经不再陌生.蓦然回首,你会发现喜欢的商品就在显眼处.如何设计推荐系统,让消费者更方便地从海量商品中找到自己的最爱,阿里工程师一直在不断探索更优的算法和技术. 阿 ...

最新文章

  1. Linux命令行笔记
  2. 在PHPStorm中支持ThinkPHP代码提示
  3. DevOps笔记-05:IT行业中BA、SM、PO、PM、PD、Dev、Ops、QA都是什么角色
  4. RHEL部署ipa红帽身份验证
  5. sql 统计用的sql
  6. 浅谈 SSD,eMMC,UFS
  7. leetcode49. 字母异位词分组
  8. 有趣的反直觉的“三门问题”
  9. MyBatis 简介、 环境搭建、数据库连接池、查询方式
  10. enum中使用中文 unity_自定义Unity材质Inspector之枚举类型(Enum)
  11. 蚂蚁森林:国庆节前组织网友去阿拉善等三地参与秋季验收
  12. 跨浏览器共享数据_可以让跨域要数据的模式:jsonp
  13. a标签传值乱码问题怎么解?
  14. 散粉在哪个步骤用_无限回购的散粉
  15. U盘安装Ubuntu操作系统
  16. 深度网络自适应DCC算法
  17. Android手机打开开发者模式调试App
  18. SILKY MIRACLE宣布奚梦瑶为品牌代言人
  19. Unity3D学习:结合Kinect进行游戏开发 | 孤舟博客
  20. C++ 并发编程(从C++11到C++17)

热门文章

  1. nginx 停止服务方法
  2. AMD与intel CPU型号大全(接口)
  3. 如何通过Google查找专业文献资料 [转]^_^!!
  4. C++基础知识(二)--左值右值--逻辑表达式求值优化--逗号运算符与表示式--输入输出格式控制...
  5. Java8新特性系列(Lambda)
  6. SpringCloud接入EDAS——服务发现篇
  7. python中的reduce、lambda函数
  8. android实践项目一实现简单的验证码和spinner下拉选项效果
  9. python selenium --处理下拉框
  10. Nginx配置文件nginx.conf中文详解