练习 21:二分搜索
译者:飞龙
自豪地采用谷歌翻译
二分搜索算法是一个简单方法,在已排序的元素列表中查找元素。它很容易描述为接受排序列表,并将其分成两半,直到找到它或遍历完。如果你完成了练习 20,那么这个练习应该比较容易。
如果我们想在已排序的数值列表中找到数字X
,我们将这样做:
- 获取列表中间的数字(
M
)并将其与X
进行比较。 - 如果
X == M
,你就完成了。 - 如果
X > M
,则在M + 1
到列表末尾的区间内寻找。 - 如果
X < M
,则在列表开头到M - 1
的区间内寻找。 - 重复它,直到找到
X
或者区间为空。
这适用于任何可以比较相等性的东西。它适用于字符串,数字和任何你可以排序的东西。
挑战练习
你的BSTree应该已经有了一个get
操作,类似于二分搜索。不同的是BSTree
已经分块了,所以没有必要再这么做了。在本练习中,你将为DoubleLinkedList
和Python list
实现二分搜索,并将其与BSTree.get
的性能进行比较。你的目标是学习以下内容:
- 对于简单的寻找元素,
BSTree
与 Python 的list
相遇效果如何? -
DoubleLinkedList
的二分搜索有多糟糕? -
BSTree
的病态情况是否也会对list
的二分搜索造成问题?
分析性能时,请不要包含排序数字所需的时间。这在进行全局优化时很重要,但在这种情况下,你只需要关心二分搜索的工作速度。你也可以使用 Python 内置列表的排序算法对list
进行排序,因为这不是重点。这个练习完全关于,三种数据结构之间的搜索速度有多快。
研究性学习
- 找出该算法需要执行的,最大的可能的比较数量。首先尝试自己弄清楚,然后研究算法来找出真正的答案。之后记住真正的答案。
- 这里的任何优化可以应用于排序算法吗?
- 尝试在每个数据结构中,可视化该算法正在做什么。例如,在
DoubleLinkedList
中,你几乎可以将其视为来回遍历,直到找到结果。 - 为了给自己一个额外的挑战,尝试使
DoubleLinkedList
成为一个有序的链表,其中每次插入始终在排序后的位置。现在编写你的性能分析,包括添加元素和排序数字列表,来了解如何提高总体性能。
深入学习
研究其他搜索算法,特别是字符串。因为 Python 的字符串的实现方式,其中许多将很难在 Python 中实现,但是试一试吧。