第一章 算法簡介
1 二分查找
二分查找是一種算法,其輸入是一個有序的元素列表。如果要查找的元素包含在列表中,二分查找返回其位置;否則返回null。
猜想1-100中的一個數字,7次內就能猜到。
如果是在240000個單詞的字典中找尋一個單詞,只需要18步。
對於包含n個元素的列表,用二分查找最多需要logn步(這里log都是以2為底的),簡單查找最多需要n步。
PS:僅當列表是有序的時候,二分查找才有效
python代碼(這個好像只是簡單查找呢):
def binary_search(list, item): #定義一個查找函數,接受參數列表和查找值 low = 0 #low代表第一個索引 high = len(list)-1 #high代表最后一個索引 while low <= high: mid = (low + high) #取中間索引值 guess = list[mid] #中間索引對應列表中的值賦給猜想值 if guess == item: #如果猜想值==查找值 return mid if guess > item: #如果大於,那么就要要調整high的索引值,用mid-1代替,因為mid不是 high = mid - 1 else: #小於則是low low = mid + 1 return None my_list = [1, 3, 5, 7, 9] print(binary_search(my_list, 3)) print(binary_search(my_list, -1))
練習:
1.1 假設有一個包含128個名字的有序列表,你要使用二分查找在其中查找一個名字,請
問最多需要幾步才能找到?
log128 = 7 , 最多需要七步找到。
1.2 上面列表的長度翻倍后,最多需要幾步?
log256 = 8 , 最多需要八步找到。
2 運行時間
最多需要猜測的次數與列表長度相同,這被稱為線性時間(linear time)——O(n)
二分查找的運行時間為對數時間(或log時間)——O(logn)
3 大O表示法
大O表示法讓你能夠比較操作數,它指出了算法運行時間的增速。
大O表示法是這樣的:
PS:大O表示法說的是最糟糕的情況。
4 一些常見的大O運行時間(又快到慢)
O(log n),也叫對數時間,這樣的算法包括二分查找。
O(n),也叫線性時間,這樣的算法包括簡單查找。
O(n * log n),這樣的算法包括第4章將介紹的快速排序——一種速度較快的排序算法。
O(n 2 ),這樣的算法包括第2章將介紹的選擇排序——一種速度較慢的排序算法。
O(n!),這樣的算法包括接下來將介紹的旅行商問題的解決方案——一種非常慢的算法。
面按從快到慢的順序列出了使用這些算法繪制網格所需的時間:
PS:算法的速度指的並非時間,而是操作數的增速。
談論算法的速度時,我們說的是隨着輸入的增加,其運行時間將以什么樣的速度增加。
算法的運行時間用大O表示法表示。
O(log n)比O(n)快,當需要搜索的元素越多時,前者比后者快得越多。
練習:使用大O表示法給出下述各種情形的運行時間
1.3 在電話簿中根據名字查找電話號碼。
O(logn)
1.4 在電話簿中根據電話號碼找人。(提示:你必須查找整個電話簿。)
O(n)
1.5 閱讀電話簿中每個人的電話號碼。
O(n)
1.6 閱讀電話簿中姓名以A打頭的人的電話號碼。這個問題比較棘手,它涉及第4章的概念。答案可能讓你感到驚訝!
O(n),大O表示法不考慮乘以、除以、加上或減去的數字
5 旅行商
旅行商要前往5個城市,同時要確保旅程最短。為此,可考慮前往這些城市的各種可能順序。
推廣到N個城市時,需要執行N!次操作才能計算出結果。
PS:算法運行時間並不以秒為單位。 算法運行時間是從其增速的角度度量的。
6 小結
二分查找的速度比簡單查找快得多。
O(log n)比O(n)快。需要搜索的元素越多,前者比后者就快得越多。
算法運行時間並不以秒為單位。
算法運行時間是從其增速的角度度量的。
算法運行時間用大O表示法表示。