前言
- 为阅读后续内容打下基础
- 编写第一种查找算法——二分查找
- 学习如何谈论算法的运行时间——大O表示法
- 了解一种常用的算法设计方法——递归
算法图解读书笔记
PS:希望可以坚持下去
一、算法简介
1.引言
1.什么是算法
算法是一组完成任务的指令。任何代码片段都可视为算法
2.需要具备的知识
要阅读本书,需要具备基本的代数知识。具体地说,给定函数f(x) = x × 2,f(5)的值是多少呢?如果你的答案为10,那就够了。
2.二分查找
1.什么是二分查找
假设要在字典中找一个以O打头的单词,你也将从中间附近开始。
现在假设你登录Facebook。当你这样做时,Facebook必须核实你是
否有其网站的账户,因此必须在其数据库中查找你的用户名。如果你的
用户名为karlmageddon,Facebook可从以A打头的部分开始查找,但更合
乎逻辑的做法是从中间开始查找。
这是一个查找问题,在前述所有情况下,都可使用同一种算法来解
决问题,这种算法就是二分查找。
2.举个例子,猜数字
下面的示例说明了二分查找的工作原理。我随便想一个1~100的数字。
你的目标是以最少的次数猜到这个数字。你每次猜测后,我会说小了、大了或对了。
假设你从1开始依次往上猜,猜测过程会是这样。
每次猜测都只能排除一个数字。如果我想的数字是99,
你得猜99次才能猜到!
1.2.1 更佳的查找方式
下面是一种更佳的猜法。从 50 开始。
小了,但排除了一半的数字!至此,你知道1~50都小了。接下来,你猜75。
大了,那余下的数字又排除了一半!使用二分查找时,你猜测的是中间的数字,从而每次都将余下的数字排除一半。接下来,你猜63(50和75中间的数字)。
这就是二分查找,你学习了第一种算法!
代码如下:
low = 0
high = len(list) - 1
//你每次都检查中间的元素。
mid = (low + high) / 2
guess = list[mid]
//如果猜的数字小了,就相应地修改low。
if guess < item:
low = mid + 1
//如果猜的数字大了,就修改high。完整的代码如下。
def binary_search(list, item):
low = 0
high = len(list)—1
while low <= high:
mid = (low + high)
guess = list[mid]
if guess == item:
return mid
if guess > item:
high = mid - 1
else:
low = mid + 1
return None
my_list = [1, 3, 5, 7, 9]
print binary_search(my_list, 3) # => 1
print binary_search(my_list, -1) # => None
* 解释下,这里为什么会有 +1 以及 -1的操作.
* 比如有如下数组:1,2,3,4,5,6,7,8
* 现在需要查找6的位置,第一次比较的话,是用4跟6做比较,6比4大,说明所需查找的元素在4的右边,即在5,6,7,8这些数中,所以开始的数值是5了,4已经被比较了,因此这里start是middle + 1
* 现在需要查找2的位置,第一次比较的话,也是用4跟2比较,2比4小,说明所需查找的元素在4的左边,即在1,2,3这些数中,所以结束的数值是3了,4已经被比较了,因此这里end是middle - 1.
3.对数函数
对 数
你可能不记得什么是对数了,但很可能记得什么是幂。log10100相当于问“将多少个10相乘的结果为100”。
答案是两个:10 × 10 = 100。因此,log10100 = 2。对数运算是幂运算的逆运算。
对数是幂运算的逆运算
本书使用大O表示法(稍后介绍)讨论运行时间时,log指的都是log2。使用简单查找法查
找元素时,在最糟情况下需要查看每个元素。因此,如果列表包含8个数字,你最多需要检查8个数字。而使用二分查找时,最多需要检查log n个元素。如果列表包含8个元素,你最多需要检查3个元素,因为log 8 = 3(23
= 8)。如果列表包含1024个元素,你最多需要检查10个元素,
因为log 1024 = 10(210 =1024)。
3.大 O 表示法
1.定义
大O表示法是一种特殊的表示法,指出了算法的速度有多快。谁在乎呢?实际上,你经常要使用别人编写的算法,在这种情况下,知道这些算法的速度大有裨益。
PS: 大 O 表示法指出了最糟情况下的运行时间
比如你查100个数,第一个数就是你要的,但还是O(n)
2.一些常见的大 O 运行时间
下面按从快到慢的顺序列出了你经常会遇到的5种大O运行时间。
- O(log n),也叫对数时间,这样的算法包括二分查找。
- O(n),也叫线性时间,这样的算法包括简单查找。
- O(n * log n),这样的算法包括第4章将介绍的快速排序——一种速度较快的排序算法。
- O(n2),这样的算法包括第2章将介绍的选择排序——一种速度较慢的排序算法。
- O(n!),这样的算法包括接下来将介绍的旅行商问题的解决方案——一种非常慢的算法。
3.小结
- 二分查找的速度比简单查找快得多
- O(log n)比O(n)快。需要搜索的元素越多,前者比后者就快得越多
- 算法运行时间并不以秒为单位
- 算法运行时间是从其增速的角度度量的
- 算法运行时间用大O表示法表示