考虑这篇文章,其中说: “三元搜索的大O时间是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个,但比三元搜索树更深。对于一亿个节点的树,假设两棵树都已适当平衡,则BST的深度为〜26,对于三进制搜索树为〜16。同样,除非您有一棵大树,否则不会感觉到这种加速。
下一个问题的答案“为什么不进一步进行n元搜索?” 很有趣。实际上,有一些更进一步的树,例如b树和b +树。它们在数据库或文件系统中大量使用,并且可以从父节点派生100-200个子节点。
为什么?因为对于这些树,您需要为访问的每个单个节点调用IO操作。您可能知道,这比代码执行的内存操作花费了很多钱。因此,尽管您现在必须在每个节点中执行n-1个比较,但是与与树的深度成比例的IO成本进行比较相比,这些操作在内存操作中的成本显得微不足道。
至于内存操作,请记住,当您有一个包含n个元素的n元树时,基本上就有了一个数组,该数组具有O(n)搜索复杂度,因为现在所有元素都在同一节点中。因此,在增加ary的同时,它一度停止提高效率,并开始实际上损害性能。
那么,为什么我们总是偏爱BSt即2元而不是3或4等呢?因为它的实现要简单得多。就是这样,这里没有什么大不了的谜。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句