演算法快學筆記(一):演算法入門
阿新 • • 發佈:2018-12-31
1. 演算法的定義
“演算法”一詞在不同的書籍以及網站上可能會存在一些差異,但是下面的定義個人覺得最為貼切:
1. 演算法代表著用系統的方法描述解決問題的策略機制
2. 能夠對一定規範的輸入,在有限時間內獲得所要求的輸出
3. 一個演算法的優劣可以用空間複雜度與時間複雜度來衡量
2. 論優秀演算法的重要性
在很多場景下,資料規模越大,越能體現優秀演算法的價值,接下來將以猜數遊戲為例進行說明優秀演算法的重要性。
假設 A隨便想了一個1到100中的某個數字讓B猜,B可以有兩種方案:
- 簡單查詢:從1開始猜,一直猜到A想的數字為止。
- 二分查詢:一半一半的猜,先猜50,如果小了,這時候就排除了1-50的數字!。接下來,你猜75,如果大了,就排除了75-100。以此類推。
接下來對兩種方式進行說明與比較
2.1 簡單查詢
該方法的優點是簡單,只需要從1一個個的猜,就一定能猜到。但是如果猜測數字的範圍非常的大,且猜的數字非常靠後,將會使用較多的時間。
2.2 二分查詢
二分查詢是一種演算法,其輸入是必須是一個有序的元素列表。每次猜都從列的中間元素開始,如果大了,就過濾掉比猜測值小的那一半數字,反之亦然。
實現程式碼如下:
// 使用二分查詢法,在有序列表intList中查詢target,返回對應的索引 func BinarySearch(intList []int, target int) int { start := 0 end := len(intList) - 1 for { if end <= start { break } mid := int((start + end) / 2) if intList[mid] == target { return mid } // 如果mid處的值大於目標值,就在mid之前的資料中搜索 if intList[mid] > target { end = mid-1 } // 如果mid處的值大於目標值,就在mid之後的資料中搜索 if intList[mid] < target { start = mid+1 } } return -1 }
2.3 簡單查詢VS二分查詢
如果列表包含100個數字,簡單查詢的方式可能要找100次才能找到結果,而二分查詢法由於每次查詢都會過濾掉一半的資料,因此最多隻需要7次(log100)就能找到結果。這個級別的資料,結果看起來差距還不是很大。
如果列表包含40億個數字,簡單查詢的方式可能要找40億次才能找到結果,而二分查詢法最多隻需要32次(log40億)就能找到結果。這個級別的資料,差距就比較可觀了。
假設B一秒鐘能猜10個數字,通過簡單查詢要猜4629(40億/10 秒)天,而通過二分查詢只需要4秒(log40億/10 秒)。
有上面的例子可以看出,一個優秀的演算法是多麼的重要!
注意:log指的都是log2
大O表示法
大O表示法指出了演算法有多快(O為運算元:Operations)。例如,假設列表包含n個元素。簡
單查詢需要檢查每個元素,因此需要執行n次操作,使用大O表示法,
這個執行時間為O(n)。二分查詢需要執行log n次操作,使用大O表示法的執行時間為 O(log n)。
關於大O表示法有以下幾點需要注意:
- 大O表示法讓你能夠比較運算元,它指出了演算法執行時間的增速,代表隨著資料集的增加,演算法所需時間的變化趨勢。
- 大 O 表示法指出了最糟情況下的執行時間
下面按從快到慢的順序列出了常見的5種大O執行時間:
- O(log n),也叫對數時間,這樣的演算法包括二分查詢。
- O(n),也叫線性時間,這樣的演算法包括簡單查詢。
- O(n * log n),這樣的演算法包括快速排序(一種非常快的排序演算法)
- O(n^2),這樣的演算法包括選擇排序(一種非常慢的排序演算法)。
- O(n!),這樣的演算法包旅行商問題的解決方案-一種非常慢的演算法。
總結
- 二分查詢的速度比簡單查詢快得多。
- O(log n)比O(n)快。需要搜尋的元素越多,前者比後者就快得越多。
- 演算法執行時間是從其增速的角度度量的。
- 演算法執行時間用大O表示法表示。