算法導論在本章爲我們展開了算法的畫卷,介紹了幾種基礎的算法,並深化了其中的思想,讓我們一起來看看。
插入排序
首先來看問題的描述:
我在代碼大全裏介紹過隱喻,現在在把它拿來再合適不過了。我們可以把插入排序看着是撲克牌,ok這樣就好理解多了。
假設桌子上有幾張牌{ 3, 9, 6, 10, K, J, 5}(我們忽略花色),現在我們要打牌,我們需要將牌進行排序,我們會這樣做:
- 先抓一張3
- 再抓一張9,比較一下9 > 3,把牌插在3後面
- 再抓一張6,比較一下6 > 3且6 < 9,我們把牌插在3和9直接
- 重複執行
ok,我們就很容易地實現了一個插入排序的過程,其實很多算法就是在我們生活中,只是我們沒有很好地去歸納。而且通過隱喻的方式去理解複雜,抽象的概念是非常有效的。我們再來理解一下書上的僞代碼
第一行可以理解爲牌堆裏的牌,接下來把當前的牌存入臨時變量中,i表示最後一張牌的順序(一般打牌都是升序的)。那麼while中的就相當於做比較的過程,思考究竟應該把牌插哪兒,假設我們很笨,一次只能看一張牌,我們從最後一張牌開始看。如果待插牌比較大,那就不要繼續比較了,直接插在最後就行,如果待插牌比較小,我們就再往前進行比較,並且把相對大的牌往後移(這裏和實際還是有些區別的,事實上我們插牌時並不會一個個後移)。按照這樣依次抓牌,到最後我們手裏的牌就是有序的了。
ok僞代碼就如此搞定了,不難吧。
下面我們要用嚴格的數學來證明算法是正確的。
例子中是將序列{5, 2, 4, 6, 1, 3}進行排序。
證明的關鍵在於循環不等式:
- 初始化:循環的第一次迭代之前,爲真
- 保持:如果循環的某次迭代之前爲真,則下次迭代之前依然爲真
- 終止:在終止時,不等式爲我們提供一個有用的性質,有助於證明算法是正確的
這類似於數學歸納法,爲了證明某條性質成立,需要證明一個基本情況和一個歸納步。初始化爲基本情況,保持則爲歸納步。
ok,我們來看詳細的證明過程:
如此插入排序算法的正確性就得以保證了。
小結
- 通過隱喻來理解複雜抽象的概念是非常有效的
- 算法的設計是需要通過嚴格的數學證明的