考虑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)
此实现有效地每次迭代仅进行两次比较。因此,忽略计算中间点所花费的时间,它不会像二进制搜索一样有效吗?
那么为什么不进一步深入搜索呢?
(虽然,然后搜索的主要问题是中点计算的数量而不是比较的数量,虽然我不知道这是否是正确答案)。
答案 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呢?因为实施起来要简单得多。这真的,这里没什么大不了的。