【问题标题】:comparison of binary and ternary search二分查找和三分查找的比较
【发布时间】:2018-03-27 03:50:45
【问题描述】:

考虑到this post which says:“三元搜索的大 O 时间是 Log_3 N 而不是二分搜索的 Log_2 N”

这应该是因为经典的三元搜索需要 3 次比较而不是两次,但是这种实现会比二分搜索效率低吗?

#!/usr/bin/python3

List = sorted([1,3,5,6,87,9,56, 0])
print("The list is: {}".format(List))

def ternary_search(L, R, search):
    """iterative ternary search"""

    if L > R:
        L, R = R, L
    while L < R:

        mid1 = L + (R-L)//3
        mid2 = R - (R-L)//3

        if search == List[mid1]:
            L = R = mid1
        elif search == List[mid2]:
            L = R = mid2            
        elif search < List[mid1]:
            R = mid1
        elif search < List[mid2]:
            L = mid1
            R = mid2
        else:
            L = mid2

    if List[L] == search:
        print("search {} found at {}".format(List[L], L))
    else:
        print("search not found")


if __name__ == '__main__':
    ternary_search(0, len(List)-1, 6)

这个实现每次迭代只需要两次比较。那么,忽略计算中点所花费的时间,它不会像二分搜索一样有效吗?

那么为什么不进一步进行一元搜索呢?

(虽然,搜索的主要关注点是中点计算的数量而不是比较的数量,虽然我不知道这是否是正确的答案)。 p>

【问题讨论】:

  • 由于 O(log_2 N) = O(log_3 N),您所指的帖子毫无意义。不过,答案是正确的。如果操作正确,二分搜索在最坏情况下的比较会更少。
  • @MattTimmermans ,我在上面已经指出,上面的三元搜索每次迭代只进行两次比较,所以,在最坏的情况下,这不是一样吗?
  • 二分查找每次迭代只需要做一次比较。请参阅:stackoverflow.com/questions/39416560/…。此外,您进行了 4 次比较,因为 == 很重要。
  • 三元搜索可能会更快。尽管每次迭代进行更多比较,但每次迭代比二分搜索的单次迭代更能减少剩余的搜索空间,从而导致更少的迭代。我并不是说它会更快,只是可以想象它可能。然而,渐近地,这两种结构具有相同的复杂性。

标签: python-3.x data-structures


【解决方案1】:

虽然两者都具有对数复杂性,但对于足够大的树,三元搜索将比二分搜索更快。

虽然二分查找每个节点少了 1 次比较,但它比三叉查找树更深。对于一亿个节点的树,假设两棵树都适当平衡,BST 的深度约为 26,对于三元搜索树,它约为 16。同样,除非您有一棵很大的树,否则不会感觉到这种加速。

您下一个问题的答案“为什么不进一步进行 n 元搜索?”很有趣。实际上有更进一步的树,例如 b-tree 和 b+-tree。它们在数据库或文件系统中大量使用,并且可以从父节点产生 100-200 个子节点。

为什么?因为对于这些树,您需要为您访问的每个节点调用一个 IO 操作;您可能知道这比您的代码执行的内存操作成本要高得多。因此,尽管您现在必须在每个节点中执行 n-1 比较,但与与树深度成正比的 IO 成本相比,这些在内存操作中的成本相形见绌。

至于内存操作,请记住,当你有一个包含 n 个元素的 n 叉树时,你基本上有一个数组,它具有 O(n) 的搜索复杂度,因为所有元素现在都在同一个节点中。因此,在增加 ary 的同时,它有时会停止提高效率并开始实际损害性能。

那么为什么我们总是更喜欢 BSt,即 2-ary 而不是 3 或 4 等?因为实现起来要简单得多。就是这样,这里没有什么大谜团。

【讨论】:

    猜你喜欢
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-24
    • 2017-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多