【算法】算法圖解筆記_算法簡介

在讀《算法圖解》這本書,這本書有兩個優點:

  1. 手繪風格的圖,看着很讓人“入戲”;
  2. 算法採用Python語言描述,能更好的表達算法思想。

關於算法的學習有兩點心得:

  • 算法思想最重要,理解了思想,算法是很容易寫出來的,所以儘量不要把過多精力放在細節上。
    比如,本書的快速排序,使用了列表推導式,很簡單就把算法的思想描述了出來。相比而言,某些使用C語言的書籍給出的版本則比較難懂,歸其原因是因爲太突出細節了。細節不是不重要,而是我們要首先把算法能更好地理解,下一步纔是實現和優化。
  • 某些情況下遞歸比迭代更容易表達算法
    遞歸是描述性的,側重了對算法性質的表達;而迭代更側重算法實現,往往摻雜了太多的實現細節。所以,我同時用Haskell給出遞歸版本的算法描述。

好了,開始。

引言

算法是一組完成任務的指令。任何代碼片段都可視爲算法。
[注意:該書對算法的定義與通行的定義不同,通行的定義要求算法應該具有有窮性,即算法必須能在執行有限個步驟之後終止,否則算法是沒有意義的。]

在本書中,你將學習比較不同算法的優缺點:該使用合併排序算法還是快速排序算法,或者該使用數組還是鏈表。僅僅改用不同的數據結構就可能讓結果大不相同。

二分查找(binary search)

其輸入是一個有序的元素列表;查找的元素包含在列表中,二分查找返回其位置;否則返回 Nothing。
一般而言,對於包含n個元素的列表,用二分查找最多需要log2n步。

Python版本:

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

Haskell版本:使用了Vector,因爲標準庫的列表是單鏈表,不支持隨機訪問。

import qualified Data.Vector as V

binarySearch :: (Ord a)=>  V.Vector a -> Int -> Int -> a -> Maybe Int
binarySearch vec low high e
          | low > high = Nothing
          | vec V.! mid > e = binarySearch vec (mid+1) high e
          | vec V.! mid < e = binarySearch vec low (mid-1) e
          | otherwise = Just mid
          where
              mid = low + ((high-low) `div` 2)

大 O 表示法

僅知道算法需要多長時間才能運行完畢還不夠,還需知道運行時間如何隨列表增長而增加。

算法的運行時間以不同的速度增加

算法的速度指的並非時間,而是操作數的增速。談論算法的速度時,我們說的是隨着輸入的增加,其運行時間將以什麼樣的速度增加。大 O 表示法讓你能夠比較操作數,它指出了算法運行時間的增速。
clipboard.png

大 O 表示法指出了最糟情況下的運行時間

這是一個保證——如,簡單查找的運行時間不可能超過O(n)。

一些常見的大 O 運行時間

 O(log n),也叫對數時間,這樣的算法包括二分查找。
 O(n),也叫線性時間,這樣的算法包括簡單查找。
 O(n * log n),這樣的算法包括快速排序——一種速度較快的排序算法。
 O(n2),這樣的算法包括選擇排序——一種速度較慢的排序算法。
 O(n!),這樣的算法包括旅行商問題的解決方案——一種非常慢的算法

旅行商問題

旅行商要前往n個城市,同時要確保旅程最短,時間複雜度:O(n!)。

請關注我的公衆號哦。
clipboard.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章