# 练习 21:二分搜索
> 原文:[Exercise 21: Binary Search](https://learncodethehardway.org/more-python-book/ex21.html)
> 译者:[飞龙](https://github.com/wizardforcel)
> 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/)
> 自豪地采用[谷歌翻译](https://translate.google.cn/)
二分搜索算法是一个简单方法,在已排序的元素列表中查找元素。它很容易描述为接受排序列表,并将其分成两半,直到找到它或遍历完。如果你完成了练习 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 中实现,但是试一试吧。
- 笨办法学 Python · 续 中文版
- 引言
- 第一部分:预备知识
- 练习 0:起步
- 练习 1:流程
- 练习 2:创造力
- 练习 3:质量
- 第二部分:简单的黑魔法
- 练习 4:处理命令行参数
- 练习 5:cat
- 练习 6:find
- 练习 7:grep
- 练习 8:cut
- 练习 9:sed
- 练习 10:sort
- 练习 11:uniq
- 练习 12:复习
- 第三部分:数据结构
- 练习 13:单链表
- 练习 14:双链表
- 练习 15:栈和队列
- 练习 16:冒泡、快速和归并排序
- 练习 17:字典
- 练习 18:性能测量
- 练习 19:改善性能
- 练习 20:二叉搜索树
- 练习 21:二分搜索
- 练习 22:后缀数组
- 练习 23:三叉搜索树
- 练习 24:URL 快速路由
- 第四部分:进阶项目
- 练习 25:xargs
- 练习 26:hexdump
- 练习 27:tr
- 练习 28:sh
- 练习 29:diff和patch
- 第五部分:文本解析
- 练习 30:有限状态机
- 练习 31:正则表达式
- 练习 32:扫描器
- 练习 33:解析器
- 练习 34:分析器
- 练习 35:解释器
- 练习 36:简单的计算器
- 练习 37:小型 BASIC
- 第六部分:SQL 和对象关系映射
- 练习 38:SQL 简介
- 练习 39:SQL 创建
- 练习 40:SQL 读取
- 练习 41:SQL 更新
- 练习 42:SQL 删除
- 练习 43:SQL 管理
- 练习 44:使用 Python 的数据库 API
- 练习 45:创建 ORM
- 第七部分:大作业
- 练习 46:blog
- 练习 47:bc
- 练习 48:ed
- 练习 49:sed
- 练习 50:vi
- 练习 51:lessweb
- 练习 52:moreweb