本欄目(Algorithms)下MIT算法導論專題是我的對網易公開課MIT算法導論的學習心得與筆記。全部內容均來自MIT公開課Introduction to Algorithms中Charles E. Leiserson和Erik Demaine老師的講解。(http://v.163.com/special/opencourse/algorithms.html)html
第一節-------課程簡介及算法分析 Analysis of algorithm算法
算法分析:關於計算機程序在效率和資源利用方面的理論研究。安全
第一節課的內容相對來講比較簡單,可是大牛就是大牛,可以把抽象的東西說的至關形象,讓人過目不忘的同時去思考背後的原理。總結一下,主要有如下幾個知識點。學習
1.算法分析的主要內容是效率,有比效率更重要的嗎?固然有,好比正確性、可維護性、可擴展性、健壯性、安全性等等,能夠想象獲得之前不少在軟件工程中談論到的重要的東西。既然如此,爲何還要進行算法的效率分析呢?在課上老師說了一個頗有意思的比方,你認爲錢重要仍是水和飯重要?固然是水和飯,錢是不能保證人的生存的,可是錢卻能夠換來水和飯。而算法分析中的「效率」就至關於「錢」,你能夠用「效率」來換取其餘東西,好比安全性,穩定性等等。它只是一個交換物,但咱們,卻離不開它。htm
2.衡量效率的因素。既然效率如此重要,咱們用什麼因素來衡量一個程序效率的高低呢?運行時間。對於同一組輸入,你的程序運行時間比別人的短,就說明你的程序在這組數據集上的效率比別人的高。排序
對於運行時間,須要考慮的因素有以下三個:遞歸
a、數據的輸入狀況。例如,對於插入排序算法來講,一個已經排好序的序列更容易排序;ci
b、數據的規模。很顯然,短的序列要比長序列更容易排序;資源
c、找到運行時間上界。通常狀況下,咱們須要找到這個程序對於最壞的輸入數據的狀況下,運行時間是多長。畢竟,每一個人都想獲得一個guarantee。get
3.幾種分析運行時間的方法T(n)。
Worst-case:(usually) —— 用T(n)來表示算法在輸入規模爲n時的最大運行時間。它的做用就是你能夠用它來給別人作出承諾,即個人算法在最壞的狀況下的運行時間也不會超過T(n)。
Average-case:(sometimes)—— 用T(n)來表示算法在全部輸入規模爲n的序列的運行時間的一個指望值。固然它的前提是假設輸入的統計機率分佈,也就是說對於一個規模爲n的輸入數據,它全部的排列方式出現的機率是相等的。
Best-case:(bogus)——而若是你想騙人,用一組極好的數據在一個效率極低的算法上跑,咱們稱之爲算法的運行時間的最好狀況,這是不夠說服人的。
4.Big Idea——漸近分析。
咱們一般所說的運行時間,都會存在一個相對時間與絕對時間的區別。好比在一臺巨型機和在一臺微機上運行同一個程序,所用的時間顯示是不一樣的。這是咱們就須要引入一個更加宏觀的概念:漸近分析——對於一個算法的運行時間,忽略那些依賴於機器的常量;忽略全部的低階項,只分析最高階項;關注於運行時間的增加,而不只僅只是運行時間。引入一個助記符號θ(n),舉一個例子:若是一個算法的運行時間爲:3n^3 + 2n^2 + 4n + 1,那麼忽略掉依賴機器的常量1,以及全部的低階項2n^二、4n,那麼這個算法的時間複雜度就爲θ(n^3)。
在這裏,老師也進行了很形象的說明。若是算法A的漸近時間複雜度是θ(n^3),算法B的是θ(n^2),那麼必定存在一個足夠大的n,使得當數據規模大於n時,算法B的運行時間要小於A,無論算法A一開始的優點有多麼大,無論算法B的漸近複雜度的係數和常數有多麼大,都沒有用。用這樣一個助記符就能夠將時間複雜度的分析獨立於機器,獨立於具體的常數,對咱們分析算法將會十分有利。
5.兩個例子——插入排序、歸併排序
插入排序的思想就是,對於每個A[i],考慮A[1...i-1]中它的合適的插入位置k,而後將A[k...i-1]依次後移一個位置,把A[i]插入到A[k]的位置便可。
上面就是插入排序的僞代碼,用縮進表明算法的層次。對插入排序作漸近分析,以下圖所示。下面一系列分析過程說明了插入排序的漸近時間複雜度是n^2級別的。
所謂歸併排序,舉個例子,歸併排序遞歸處理的兩個表已經有序了,爲{2, 7, 13, 20}和{1, 9, 11, 12}。
咱們如何合併這兩個表呢?這兩個表已是有序的了,咱們要找出當前表中剩下的最小元素,這個最小元素必定是在表1的頭部或表2的頭部,而後取出來,放入總的表中,此時咱們取出了1這個元素。那麼表2中還剩下3個元素,而後再接着比較表1和表2,找出最小的元素,爲2,這樣咱們依次找下去,即可以將兩個有序表合併成一個有序表。以下圖所示。
下圖是歸併排序的僞代碼以及算法漸近分析。
下面咱們用遞歸樹的方法來分析這個算法的運行時間,首先寫出運行時間的遞歸表達式:若是咱們考慮n>1的狀況,T(n) = 2T(n/2) + Cn,其中C爲一個常數。畫成遞歸樹的形式以下圖所示:
那麼,咱們看一下上面第三幅圖,第一行的時間和爲Cn,第二行的時間和爲C(n/2)+C(n/2) = Cn,...,第lgn行的時間的和爲θ(n)。其中,lgn爲樹的高度,簡單分析便可得出。
那麼一共lgn行,每行時間和爲Cn,簡單計算便可知這棵遞歸樹的總的時間和(即算法的漸近時間和)爲 (Cn)lgn + θ(n),忽略低階項θ(n),即算法的漸近時間複雜度爲θ(nlgn)。
講到這裏,第一節的內容也就快結束了。老師最後給出了一個結論:歸併排序可以在效率上當輸入規模n增大的時候漸近的超過插入排序,在最壞的狀況下。實際上,當n>30以及以上的時候,歸併排序的效率就比插入排序的效率要高了。Go test it out for yourself!
關於Introduction to Algorithms更多的學習資料將繼續更新,敬請關注本博客和新浪微博Sheridan。