一、插入排序
插入排序屬於原址排序,演算法在陣列a中重排元素,演算法思想與玩撲克牌時依次將抓到的牌放到手中合適的位置一致,當輸入完成時,手中的牌即已完成排序。
插入排序(a)
for j = 2..a.length setp = 1 //a 下標從 1 開始計數
key = a[j]
i = j - 1
while i > 0 && a[i] > key
a[i + 1] = a[i]
--ia[i + 1] = key //當 i == 0 || a[ i ] <= key 時,插入尋找退出,此時的 key 應該放到 a[ i ] 的下乙個單元 a[ i ]+ 1
演算法的時間複雜度為o(n^2)
二、分治模式
分治思想:將原問題分解為幾個規模較小的但類似於原問題的子問題,遞迴的求解這些子問題,然後合併這些子問題的解來建立原問題的解。
步驟:分解:分解原問題為若干個子問題,這些子問題是原問題的規模較小的的例項
解決:遞迴地求解這些子問題,子問題足夠小,可直接求解
合併:合併子問題的解為原問題的解
演算法的核心在於 合併 操作,對於陣列 a ,p,q,r 為陣列下標,滿足 p <= q < r,假定子陣列 a[ p..q ] 和 a[ q + 1,r] 都已排好序,下面的例程將合併這兩個子陣列形成單一
的已排好序的子陣列a[ p..r ]:
合併(a,p,q,r)
n1 = q - p + 1
n2 = r - q
new array l[ n1 + 1 ] and r[ n2 + 1 ]
for i = 1..n1 step = 1
l[ i ] = a[ p + i - 1] //l陣列為 [p,q]
for j = 1..n2 step = 1
r[ j ] = a[ q + j ]
l[ n1 + 1 ] = 哨兵
r[ n2 + 1 ] = 哨兵
i = j = 1
for k = p .. r
if l[ i ] <= r[ j ]
a[ k ] = l[ i ]
++ielse
a[ k ] = l[ j ]
++j
有了這個合併例程,根據分治思想,歸併排序演算法水到渠成:
歸併排序(a,p,r)
if p < r
q = (p + r)/2 //向下取整
歸併排序(a,p,q)
歸併排序(a,q + 1,r)
合併(a,p,q,r)
演算法的時間複雜度為o(nlgn)
三、遞迴式的求解
歸併排序演算法複雜度的計算符合遞迴式:
t(n) = at(n/b) + f(n)
其中,a >= 1,b > 1是常數,f(n) 是漸進正函式,關於這個遞迴式的求解有很多種方法,最常用的當屬 主方法,主方法依賴於主定理:
定理:令 a >= 1,b > 1 是常數,f(n) 是乙個函式,t(n)是定義在非負整數上的遞迴式:t(n) = at(n/b) + f(n)
那麼,t(n) 有如下漸進界:
1.若存在某常數 c > 0 有 f(n) = o(n^(logb(a-c))),則t(n) =o(n^(logb(a)))
2.若 f(n) = o(n^(logb(a))),則 t(n) = o(n^(logb(a))lgn)
3.若對於某常數 c > 0 有 f(n) = ω(n^(logb(a + c))),且對某個常數 c < 1 和所有足夠大的 n 有 af(n/b) <= cf(n),則t(n)=o(f(n))
演算法導論學習總結 基礎篇 一
一 基礎知識 概念 總結 1.漸進記號 1 大o記號 大o記號給出函式的漸進上界。定義 o g n ps 記號是乙個比o記號更強的概念。按集合論的寫法,有 g n 包含於 o g n 2 大 記號 正如o記號提供了乙個函式的漸進上界,記號提供了漸進下界。定義 g n 3 大 記號 大 記號給出函式的...
演算法導論學習筆記 1 基礎排序演算法
最近從頭開始學習演算法導論,作為乙個非計算機專業的學生,我的目的也就是為了找工作的時候能多點籌碼 但是學習過程中還是有不少收穫的,順便也能練習下python程式設計水平,因此記錄下學習內容 第一章是演算法基礎,這裡介紹了2種排序方法 插入排序和歸併排序 例子還算比較淺顯易懂。對於插入排序,可以用乙個...
演算法導論之演算法基礎(三)
插入排序 模擬 如果你會玩鬥地主,那麼摸牌後按從小到大插入,你這樣插入的過程就是插入排序 程式 在程式中的玩法就像有乙個人發牌,發齊了再拿牌,也就是一開始你就有17張牌,這17張牌對應17個元素的陣列。你從第二種牌開始進行調動,如果第二張牌比第一張牌小,那麼就把第二張牌抽出來,然後把第一張牌放入到第...