主題:簡介課程,漸近概念的大局觀,插入排序和歸併排序,遞歸式函數時間分析(遞歸樹方法)算法
教材:《算法導論》安全
收穫:很感動地看到算法分析那個log(n)是爲何出現了,更深層還要聽第二講,若不是由於要準備SAS,巴不得立刻看。ide
內容:模塊化
1 何爲算法分析?函數
計算機程序運行性能和存儲空間的理論分析,叫算法分析。也就是關注2點:1 性能,就是程序跑得快不快; 2 存儲空間,即佔用了多大的內存。可是主要仍是關注性能。(多是由於時間就是金錢吧,並且如今計算機硬件發展速度還不錯)性能
2 比性能更加劇要的因素都有哪些?學習
好比成本,正確性,功能特徵(features),用戶用好,模塊化性等等。idea
3 那爲什麼還學習算法和性能?spa
很妙的引入方法,你都說了上面那些東西比性能還重要,那尼瑪幹嗎還要學習算法?設計
學習算法的緣由:
A performance measures the line between the feasible and the infeasible.
對於不少比性能更重要的因素,其實他們跟性能是密切相關的,好比用戶用好,就須要你的程序響應時間控制在必定範圍內。算法老是處在解決問題的最前沿。
B algorithms give us a language for talking about program behavior.
算法給出了程序行爲的描述。
其實形象的比喻就是:水,食物這些東西都比錢重要,你爲何還須要錢?算法就像經濟社會中的「貨幣」,它給出了衡量的通常標準。好比你付出了性能來追求安全穩健性,用戶友好性等等。
好比JAVA程序一直很流行,其實它的性能比起C語言要差3倍多,可是因爲它自己的面向對象,異常機制等緣由,使得人們仍是很願意犧牲性能來追求可拓展性,安全性這些東東。我的的理解就是,好比在軟件設計中,你要着重追求某些方面,那在哪一種程度範圍內是能夠接受的呢?性能就是一個標準,好比犧牲3倍性能能夠接受,10倍就不行。
C tons of fun
追求速度老是頗有趣的,因此人們纔會熱衷於賽車,火箭等東西。
4 引入插入排序
插入排序(Insertion Sort)
4.1 描述:
輸入 A[1…n],要輸出 A’[1,…n],使得A’中的元素按升序排序,也就是a’(1)<=a’(2)<=a’(3)…
4.2 僞代碼:
For j=2 to n
{
Do key=a[j]
i=j-1;
While i>0 and a[i]>key
{
Do a[i+1]=a[i]
I=i-1;
}
A[i+1]=key
}
4.3 舉例:
1 7 3 6 4 20 13 9
T1:看第二個元素,7,比1大,放在第二位
T2:看第三個元素,3,比7小,把7放到第三位,3再跟1 比較,比1大,因此3放在第二位,結果1 3 7
T3:相似,分析6,結果1 3 6 7
T4..
T7:1 3 4 6 7 9 13 20
4.4 本質:
每次循環後前面已經排好序的部分保持不變(這裏的不變應該是指不用管了,而不是位置絕對不變),每次循環的目的是完成增量,使得已經排序的長度+1
5 經過插入排序,看運行時間依賴哪些因素,引入算法分析的漸近分析符號
5.1 運行時間依賴因素
A 輸入的數列,若是已經排好序,工做量近似爲0,而若是是逆序的,工做量最大
B 輸入的數列規模n。6個數VS 6億個數,因此後續的運行時間分析時,咱們把時間當作是n的函數
5.2 T(n)引入
通常咱們都想知道運行時間的下屆,就是最差的狀況,這樣子對用戶是一個保證,你能夠跟人家說這個程序最多不超過3s,可是你不會說最少要3s吧,天知道最好3s,最差要多久,說不定是一生。
因此在算法分析中,咱們通常是作最壞狀況分析,能夠用T(n)表示最長的運行時間,
T(n)is the max time on any input size n.
有時候咱們也討論平均狀況。此時T(n) is the expected time over all input size n.也就是T(N)表示指望時間。
(什麼是指望時間,數學上的公式是每種輸入運行時間*每種輸入出現的機率,通俗來說就是加權平均。)
那麼每種輸入出現的機率是多大呢?咱們假設一種統計分佈:均勻分佈,固然也能夠選擇其餘分佈。均勻分佈,也就是說,每種輸入出現的機率是同樣的。
最好狀況分析,這個是假象,通常是拿來忽悠人的。沒什麼用。
運行時間依賴於具體的機器,因此通常分析的時候是考慮相對速度,也就是在同一臺機器上的運行速度。(相反的就是絕對速度,也就是在不一樣機器上作比較)
6 算法的大局觀:The Big idea of algorithm——漸近分析
6.1 基本思路是:
忽略掉那些依賴於機器的常量(好比某條具體操做運行時間,如賦值操做),並且,不是去檢查實際運行時間,而是關注運行時間的增加。什麼意思呢?就是關注的是當輸入規模n——》無窮時,T(n)是什麼狀況,而不是說n=10的時候的詳細比較。
6.2 具體
漸近符號:Θ(n)
運算法則:對於一個公式,棄去它的低階項,並忽略前面的常數因子。好比
Θ(3n^3+90n^2-5n+69)=Θ(n^3)
簡單吧!
其實Θ(n)是有嚴格的數學定義的(下節課再一塊兒講),因此算法導論這門課既是講數學,也是講計算機科學的。
6.3 數學與工程的trade-offs
從圖中(這個圖畫得不是通常的醜)能夠看出,當n0趨於無窮時,Θ(n2)<<Θ(n3)
有時候交點n0太大,計算機沒法運行,因此咱們有時會對一些相對低速算法感興趣。應該就是理論與實際的妥協trade-offs。
7 插入排序運行時間分析
插入排序最壞狀況:
T(n)=2+3+…+n=(2+n)(n-1)/2=Θ(n^2)
插入排序算不算快?
對於較小的n,還算是很快的,可是對於大n,它就不算快了,更快的一種排序算法是歸併排序。
8 引入歸併排序
8.1 歸併排序步驟
S1:若是n=1,那麼結束;
S2:不然,遞歸地排序A[1,…[n/2]]和A[[n/2]+1,…n]
S3: 將2個已經排序好的表合併在一塊兒(’Merge’)
8.2 歸併子程序
這裏用到了一個歸併子程序,這也是這個算法的關鍵。
假設2張已經按照從小到大排序好的表,如何合併?
由於最小的元素必定是2張表中首個元素之一。因此每次對比2張表中最小元素便可。
舉例:
1 7 11 13 15 19
3 4 9 18 20 22
首先比較1,3,取1,而後第一個表劃掉1
而後比較7和3,取3,而後第二個表劃掉3
而後比較7和9,取7,而後第一個表劃掉7
以此類推
這個過程運行時間是Θ(n),由於每一個元素用了一次對比,是常數時間,而後作了n次,因此是Θ(n),也就是線性時間。
9 歸併排序運行時間分析(遞歸樹方法)
因此T(n)={Θ(1) if n=1;
2T(n/2)+Θ(n)(if n>1)(注意:Θ(n)+Θ(1)=Θ(n)}
已經知道遞歸式子了,那麼運行時間如何求解?
能夠用遞歸樹的方法求解運行時間,具體的在Lecture2 會講到,咱們只要考慮n>1的狀況便可
此時T(n)能夠表示成爲2*T(n/2)+C*n
構造遞歸樹方法:
1 先把遞歸式子的左半部分寫出來
注意:式子右邊樹上的葉子加起來正好就是T(n),好比第一顆樹,T(n)=Cn+T(n/2)*2
高度(層數)約爲log(n)(視頻上寫着log(n),我的以爲應該是表示log2(n),後面也直接用log(n)表示)
這裏強調「約」,是由於n不必定是2的整數冪,可是接近。
假設n是2的整數冪,那麼講到Θ(1),正好有log(n)步,n->n/2->n/4->…1,其實是log(n)的常數倍。
最底層的葉子節點數目是n
T(n)表達式?
爲了獲得T(n),考慮把全部樹上葉子加起來是多少。
除了最後一層,每一層的綜合都是C*n,最後一層不必定是C*n,由於邊界狀況可能存在別的值,記爲Θ(n)
因此總數T(n)=Cn*log(n)+Θ(n)(第一項比第二項高)=Θ(n*logn)
考慮漸近狀況下,Θ(n*logn)比Θ(n2)要快,因此歸併排序在一個充分大的輸入規模n下將優於插入排序。
10待解決疑問:
1好比遞歸樹原理,有待下一講一些理論
2 爲何在漸近狀況下,Θ(n*logn)<<Θ(n2)