【发布时间】:2011-03-13 03:06:50
【问题描述】:
在二分查找中,我们将数组分成 2 份,然后通过递归使用二分查找再次在单个数组中进行查找。
现在,如果我使用三元搜索,而不是二分搜索,搜索会将数组分成 3。我的问题是:
- 三元搜索是否会比二分搜索快,反之亦然?
- 在什么条件下,哪种算法会执行得更好?
- 性能是否取决于数组的大小?
【问题讨论】:
在二分查找中,我们将数组分成 2 份,然后通过递归使用二分查找再次在单个数组中进行查找。
现在,如果我使用三元搜索,而不是二分搜索,搜索会将数组分成 3。我的问题是:
【问题讨论】:
从Wiki's 开始,三叉搜索树是一种三叉树,其中节点相对于搜索键是按顺序排列的。如果搜索键是字符串,则每个节点存储一个字符,并且对字符串的搜索由一系列二进制搜索组成,对于字符串中的每个字符进行一次搜索:
在二分搜索中,您只需比较并得到另一半。
但是,在您比较的三元搜索中,如果小于,则获得第一个 1/3,否则再次比较,如果小于,则获得第二个 1/3,否则获得最后一个 1/3。
在这里阅读更多:
【讨论】:
嗯,这完全取决于您所说的“更快”是什么意思。渐近地说,它们都在 O(log n) 时间内运行(从技术上讲,二分搜索在 O(log_2(n)) 中运行,而三元搜索在 O(log_3(n)) 中运行,其中 log_k 表示“log base k”;但是,它们仅相差一个常数因子,因此它们都等效于 O(log n))。因此,从算法的角度来看,这两个函数总体上运行的时间相同(即,它们具有相同的时间复杂度)。
也就是说,在某些特殊情况下,一个计算量会比另一个计算量少。例如,如果目标值正好在数组的中间,二分查找将在第一次迭代时返回该值,并且永远不会递归,而三进制则必须递归才能找到该值。类似地,如果目标值正好在数组中的三分之一处,三分查找会立即找到它,而二分查找则需要递归。
【讨论】:
如果您谈论的是单处理器系统,则没有渐近差异,并且三元搜索的开销更大。在多处理器/多核系统上,它将(在一定程度上)加速搜索以将其划分为独立的搜索(前提是执行环境/语言允许这样的划分)。但这通常最好只在顶层完成一次。
【讨论】:
我很难确定您所说的“三元搜索”是什么意思。二进制搜索将数组分成两半的原因是,您进行的每次比较都会将数组分成两个区域,元素小于考虑的元素,元素大于考虑的元素。我没有看到一种简单的方法来概括这一点,以便通过进行一次比较将数组分成三部分。
但是,如果您不将数组分成相等的两半,而是将其分成 1/3 / 2/ 3 在每次迭代中拆分,那么您仍然可以获得 O(lg n) 性能,尽管常数项会更高。事实上,对于任何常数 ε,您将数组拆分为大小为 ε / 1-ε 的片段,您将获得 O(lg n) 行为。
如果在执行比较时将数组分成大小为 εn 和 (1-ε)n 的两部分,仅在数组大小小于 1 时终止,则算法将在 k 步后终止,其中 k 是εkn kn
εkn
εk
k > logε 1/n
k > - 对数ε n
k > - lg n / lg ε
k > lg n / lg 1/ε
使用类似的逻辑,但使用 1 - ε,我们得到了
k > lg n / lg 1/(1 - ε)
请注意,由于 lg 1/ε 和 lg 1/(1 - ε) 是常数,满足这些性质的最小 k 是 O(lg n)。
【讨论】: