C 为什么BST中的搜索比二进制搜索算法快

C 为什么BST中的搜索比二进制搜索算法快,c,algorithm,C,Algorithm,我想知道为什么BST中的搜索比二进制搜索算法更快 我指的是子树中向量数(几乎)总是相同的树(平衡良好) 我已经测试了它们,在BST中搜索总是更快。为什么?不看实现就不可能知道。它们的核心是同一件事 BST需要跟随指针遍历到右半部分,而数组上的二进制搜索执行算术运算(例如加法和除法/移位)。通常,数组上的二进制搜索速度要快一点,因为它总体上遍历的内存更少(不需要存储指针),并且在算法的最后阶段更符合缓存 如果阵列变量对您来说总是比较慢,则可能是实现中出现了故障(但这是不太可能的!!)或者算法比所有

我想知道为什么BST中的搜索比二进制搜索算法更快

我指的是子树中向量数(几乎)总是相同的树(平衡良好)


我已经测试了它们,在BST中搜索总是更快。为什么?

不看实现就不可能知道。它们的核心是同一件事

BST需要跟随指针遍历到右半部分,而数组上的二进制搜索执行算术运算(例如加法和除法/移位)。通常,数组上的二进制搜索速度要快一点,因为它总体上遍历的内存更少(不需要存储指针),并且在算法的最后阶段更符合缓存


如果阵列变量对您来说总是比较慢,则可能是实现中出现了故障(但这是不太可能的!!)或者算法比所有内存开销都慢得多。

两者在速度方面应该大致相同。两者都是O(logn)。二进制搜索访问内存位置,并在每次迭代时进行比较。BST跟随指针(也是内存访问)并进行比较。大O复杂度中的常数差异应该可以忽略不计

一个可能的原因可能是,您需要在二进制搜索的每次迭代期间执行额外的计算。大多数实现都有这样一行:

mid=(high+low)/2;
与整数加法和比较运算相比,除法运算的成本可能更高。这可能会导致额外的性能开销。减少影响的一种方法是使用:

mid=(high+low)>>1;
但我认为大多数编译器无论如何都会为您优化它

BST变量不需要计算任何内容,它只是比较并遵循适当的指针


另外,可能是您正在递归地进行二进制搜索,而您的BST查询是非递归的,这使得BST更快。但是,如果不查看代码,就很难找出具体的原因。

二进制搜索算法是如何实现的?请发布您用于测试的代码。这在很大程度上取决于实现。@San:如果您想详细了解BST,您可以(应该)问同样的问题。哪种数据结构?我认为你应该插入你的代码(可能是使用向量,也可能是数组的初始化,或者…),通过提供一个二进制搜索比BST快的例子,我证明“BST总是快”这一点是错误的:查看实现可能会揭示出答案,但也可能什么都不告诉你。编译器、平台和CPU也起着作用。如果对
使用有符号整数,编译器无法为您优化
(高+低)/2
(高+低)>>1
,除非它能以某种方式确定值始终为正。因此,您应该使用无符号类型,或者自己编写
>1
版本。@R..:不知道编译器无法捕获它。现在您已经指出,编译器不知道值是否溢出是有道理的。谢谢,这不是溢油的问题。编译器可以忽略溢出。这是关于
(-1)/2
是0而
(-1)>>1
是-1的事实(至少根据C对代数的曲解)。是的,对于负数的划分至少有3种不同的定义-非常有趣(特别是因为并非所有编程语言都同意使用什么)。但是无论如何,在二进制搜索算法的情况下,编译器应该能够推断出索引总是>=0,因为它知道数组的大小必须>=0,并且起始最小位置也是0。虽然我希望这里的任何人都能使用正确的版本low+(high-low)/2,这可能不是问题,但为什么要冒险呢?