二元和三元搜索的比较

时间:2017-10-15 15:09:18

标签: python-3.x data-structures

考虑this post which says:"三元搜索的大时间是Log_3 N而不是二进制搜索的Log_2 N"

这应该是因为经典的三元搜索需要3次比较而不是2次,但这种实现是否比二进制搜索更低效?

#!/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)

此实现有效地每次迭代仅进行两次比较。因此,忽略计算中间点所花费的时间,它不会像二进制搜索一样有效吗?

那么为什么不进一步深入搜索呢?

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

1 个答案:

答案 0 :(得分:1)

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

虽然二进制搜索每个节点的比较少1,但它比三元搜索树更深。对于1亿个节点的树,假设两棵树都是适当平衡的,BST的深度将是~26,对于三元搜索树,它是~16。再说一遍,除非你有一棵非常大的树,否则不会感觉到这种加速。

你的下一个问题的答案&#34;为什么不进一步进行n-ary搜索?&#34;很有意思实际上有树木可以进一步采用它,例如b-tree和b + -tree。它们在数据库或文件系统中大量使用,并且可以从父级生成100-200个子节点。

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

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

那么为什么我们总是喜欢BSt,即2-ary而不是3或4呢?因为实施起来要简单得多。这真的,这里没什么大不了的。