`
febird
  • 浏览: 256222 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

linux kernel 中的二叉树搜索 与 stl 相应物的对比

 
阅读更多

代码

Linux kernel 中也使用并实现了红黑树,但是查找算法没有自己实现,而是希望使用者去实现。如果只是实现一个精确查找的函数,这很简单,几乎每个人都能写出正确的代码:


这是 kernel 中 rbtree.h 中给出的示例代码,几乎所有的 kernel search 代码都遵循了这个模式。然而,这个代码的效率有问题,虽然仍是 O(logn) 的。

再看看 stl 中的实现(这只是个简化示例,不完全等同于 stl 中的实际代码):


分析

kernel 代码的每个循环中有两个条件判断,而 lower_bound 中只有一个条件判断,虽然在 stl 中,即使在找到相应结点后,可能还需要再继续搜索,然而,鉴于二叉树(平衡树)的结构,深度越深的结点,其数目越多,对于满二叉树,深度增一倍,结点数目就增一倍,最底层(深度最深的那层)结点的数目比所有其它层的总数还要多1。假定满二叉树的高度为k(仅一个结点时定义该高度为0),则结点总数=2^(k+1)-1,针对查找成功的情况,假定每个结点被查找的概率相同,满二叉树的平均查找长度为:

linux kernel 的实现

(1*1+2*2+...+(k+1)*2^k))/(2^(k+1)-1) = (1 + k*2^(k+1))/(2^(k+1)-1) = k +(k+1)/(2^(k+1)-1)

(k+1)/(2^(k+1)-1) 在 k 较大时会非常快地趋近于 0,我们可以忽略这一项,结果就是k

从而,最坏情况下,循环内的判断总次数为 2*k,平均次数是 1.5*k

stl::rb_tree::lower_bound

每个结点的查找都一直到最底层,所以平均查找长度为 k+1,只多 1,然而,循环内的判断次数是 1,所以总的判断次数是 k+1,rb_tree::find 在 lower_bound找到后需要再判断一次与key 是否相等,总的判断次数就是 K+2 了,但这仍然比 kernel 的判断次数少(k>2 的时候)。虽然这是针对满二叉树的分析,但这可以延伸至平衡的二叉树(log 的底数不再是 2,要比 2 稍微小一点)。

结论

现在应该看到了,虽然std::lower_bound 没有在找到目标的第一时间就返回,看上去似乎比较傻,但实际上要更快,鉴于现在 CPU 有缓存,分支预测(这个例子循环内的分支预测无法起作用,但CPU还有 speculation,就是同时执行两个分支,然后丢弃错误的那个分支),指令预取等高级功能,lower_bound 比 kernel 快的没有分析的那么多。经过实测,stl 的 rb_tree::find 要比 kernel 的大约快 10% 。

范围查找

如果要范围查找, kernel 的那个实现就不行了,而 lower_bound 是专干这个的(当然,还有个对应的 upper_bound)!

另外,毋庸置疑,stl 的这个代码更简洁,但稍微费脑子一点。


分享到:
评论

相关推荐

    数据结构 C++ STL 二叉树

    3. **二叉树的迭代器**:在C++ STL中,虽然没有直接提供二叉树的容器,但我们可以使用迭代器来模拟对二叉树的遍历。迭代器是一种抽象的概念,它允许我们像操作数组一样操作其他数据结构,如二叉树。通过自定义迭代器...

    二叉树的深度优先搜索与广度优先搜索实现

    二叉树搜索是计算机科学中的一种常见的搜索算法,用于遍历二叉树中的所有节点。二叉树搜索可以分为深度优先搜索和广度优先搜索两种方式。本文将详细介绍二叉树的深度优先搜索和广度优先搜索的非递归方法实现。 深度...

    构造二叉树与遍历二叉树

    ### 构造二叉树与遍历二叉树 #### 一、二叉树的基本概念 二叉树(Binary Tree)是一种非线性数据结构,在计算机科学中被广泛应用于各种算法和程序设计中。一个二叉树由零个或多个节点组成,其中每个节点最多有两个子...

    STL源码剖析-简体中文PDF

    ### STL源码剖析 ...它不仅提供了丰富的代码示例,更深入浅出地揭示了STL中各种数据结构和算法的设计思想与实现细节。通过阅读本书,读者可以更加深刻地理解C++语言的魅力所在,并为后续开发工作打下坚实的基础。

    C 语言 二叉树 读文件并排序 Linux 底下

    本主题聚焦于如何在Linux环境下使用二叉树来读取文件内容,并对数据进行排序。下面将详细阐述这个过程涉及的关键知识点。 首先,我们要理解二叉树(Binary Tree)是一种非线性数据结构,每个节点包含两个子节点,...

    二叉树搜索 MIT课程英文讲义

    在MIT的这门课程中,Lec3和Lec4分别深入探讨了二叉树的基础与高级主题。 在Lec3中,首先会讲解二叉树的基本概念,包括如何通过图形化方式表示二叉树,以及如何用数组或链表实现二叉树。节点的操作是二叉树的核心,...

    数据结构实验-3二叉树遍历与路径查找(二叉树实验)

    实验三 二叉树遍历与路径查找(二叉树实验) 实现功能:建立二叉树存储结构、求二叉树的先序遍历、求二叉树的中序遍历、求二叉树的后序遍历、求二叉树的层次遍历、求根到给定结点的路径。 主控菜单: 1.建立二叉树...

    ds18b20二叉树搜索算法.pdf

    ds18b20二叉树搜索算法.pdf 这篇文章主要介绍了ds18b20二叉树搜索算法的原理和实现。下面是文章中提到的知识点: 1. 单总线技术:单总线技术是一种简单的三步操作过程的重复,即先读一位,接着读该位的反码,然后...

    二叉树演示 实现二叉树图形显示

    在计算机科学中,二叉树被广泛应用于数据的组织和操作,如搜索、排序、文件系统等。本例子关注的是如何实现二叉树的图形显示,让用户能够直观地理解二叉树的结构。 在二叉树的实现中,首先需要定义一个二叉树节点的...

    二叉树的建立与遍历

    二叉树的建立与遍历 二叉树是一种重要的数据结构,它广泛应用于计算机科学和软件工程中。在这篇文章中,我们将讨论二叉树的建立和遍历,包括先序遍历、中序遍历和后序遍历。 一、数据结构的重要性 数据结构是...

    二叉树建立 二叉树基本算法的实现

    (1)输入字符序列,建立二叉链表。...(6)对于树中每一个元素值为x的结点,删去以它为根的子树,并释放相应的空间。 (8)借助队列实现二叉树的层次遍历。 (9)在主函数中设计一个简单的菜单,分别调试上述算法。

    树与二叉树的转换

    树与二叉树之间的转换是一个重要的概念,尤其是在数据结构和算法的学习中。下面我们将详细探讨这个主题。 一、树到二叉树的转换 1. 顺序遍历法:树转换为二叉树的主要方法是通过前序遍历(Preorder Traversal)、...

    二叉树模拟器.py二叉树模拟器.py

    二叉树模拟器.py二叉树模拟器.py二叉树模拟器.py二叉树模拟器.py二叉树模拟器.py二叉树模拟器.py二叉树模拟器.py二叉树模拟器.py二叉树模拟器.py二叉树模拟器.py二叉树模拟器.py二叉树模拟器.py二叉树模拟器.py...

    将满二叉树转化为求和二叉树_二叉树_

    在IT领域,特别是数据结构和算法的学习中,二叉树是一种重要的抽象数据类型。满二叉树是一种特殊的二叉树,其中每一层都是完全填充的,除了可能的最后一层,且最后一层的所有节点都尽可能地向左靠拢。而将满二叉树...

    ds18b20二叉树搜索算法.doc

    ds18b20 二叉树搜索算法 ds18b20 是一种单总线技术的温度传感器,单总线技术搜索 ROM 的过程是主设备获取单总线上从器件的注册码的过程。该过程是一个简单的三步操作过程的重复,即先读一位,其次读该位的反码,...

    树与二叉树_习题

    在计算机科学中,树与二叉树是两种重要的数据结构,它们在算法设计、数据库管理、编译原理等领域有着广泛的应用。本节我们将深入探讨树与二叉树的相关习题和知识点。 首先,我们来看一个关于满二叉树的问题。一棵...

    python编写 实现 快速排序 和 二叉树排序 并对比速度

    python编写 实现 快速排序 和 二叉树排序 并对比速度

    二叉树的创建 遍历 交换子树

    在主函数`main`中,首先提示用户按先序输入二叉树的节点,然后调用相应的函数进行遍历和子树交换,并打印出遍历结果,供用户查看和验证。 实验的目的在于让学习者掌握二叉树的逻辑结构和不同遍历方式,以及如何使用...

    【数据结构与算法】二叉树的实现C语言代码

    在IT领域,数据结构与算法是编程的基础,而二叉树作为其中的一种核心概念,有着广泛的应用。本主题聚焦于“二叉树的实现C语言代码”,旨在通过具体实例帮助理解二叉树的相关操作。 首先,我们要理解二叉树的基本...

    树与二叉树算法总结

    树与二叉树是计算机科学中非常重要的一部分,掌握树与二叉树的算法对于数据结构和算法设计非常重要。本文将对树与二叉树的基本概念、性质、运算和应用进行总结。 一、树的基本概念 树是一种非线性数据结构,由节点...

Global site tag (gtag.js) - Google Analytics