所謂插入排序,就是排序問題的乙個演算法.
演算法的本質,就從輸入到輸出的可靠流程.
輸入:n個數的有窮序列 ,a2, ..., an > ,a2 ,.. .,an > 輸出:輸入序列的乙個排列, ′,a2 ′,.. .,an ′> ′,a 2′, ..., an′ > ,滿足∀ i ai′≤ aj ′\forall i∀i ai′ ≤aj′ 就好像乙個人從牌堆抽取撲克牌的過程. 每次抽取到牌後,放入手中該牌應該處於的位置. 無論是在抽到牌前,還是抽到牌後,手牌均處於乙個順序正確的狀態. 一直到抽完所有的牌,最終就能得到這些牌正確的順序. 譬如,手中含有(3,4,5,10),再抽到7的時候,就應該夾到5,10之間. insertion_sort (int *a,int n) a[i+1] =key; }}演算法以迴圈的形式進行. 每次迴圈開始前,a[1,j-1]相當於已經在手中排好序的牌,而a[j,n]則為還在牌堆中的牌. 每次迴圈,抽取到的牌即為a[j].要在當次迴圈中確定好它的位置,並將其放入. 迴圈不變式 乙個新的名詞. 大家可以看到,迴圈中,給定的輸入序列不斷變換,最終得到滿足要求的輸出序列. 以序列(5,2,4,6,1,3)為例,粗體為當次迴圈中所要定序的牌,即抽到的牌. 524613,j=2 254613,j=3 245613,j=4 245613,j=5 124563,j=6 123456 迴圈不變式,即在迴圈中,不斷變化的資料所滿足的,某個性質,或者是命題. 在這裡,迴圈不變式即為:每次迴圈開始前,a[1,j-1]的資料以及處於按序排列狀態. 迴圈不變式有3條性質需要證明: 1.初始化.在迴圈開始前,命題為真. 2.保持.每次迴圈不會使本命題由真變假. 3.終止.演算法結束後,迴圈不變式對我們得到要求的輸出有所幫助. 就本例而言,初始化顯然為真,j=2時a[1,1]只有乙個元素. 保持,要說清並不輕鬆. 終止:顯然j=n+1時結束,此時不變式確保了a[1,n]的元素已被排好了序,因此我們才能指出這就是我們要的輸出序列.但作者沒有使用過這個稱呼.
void
作者簡略介紹了很多ram模型的分析法,但因為過於複雜而放棄了.
輸入規模
演算法需要的時間,與演算法輸入的規模同步增長,一般來說,至少是正比例增長.
因此,通常用帶有輸入規模n的函式來描述演算法的執行時間的大概.
但輸入規模的定義依賴於問題本身.例如排序問題中,就適合以元素的數目為輸入規模,和一張圖有關的問題,規模就應該考慮圖的節點數和邊數.
因此,是乙個隨問題而靈活定義的東西.
執行時間
即演算法需要執行的基本操作的步數的時間,在輸入規模確定的情況下.
作者假設**中,每行執行的時長均為固定的常量c
ic_i
ci(第i行,共8行).
那麼只需要再確定每行**執行的次數,即可確定最終的時間了.
令輸入規模為n時,演算法的執行時間為t(n),每行**執行的次數為t
it_i
ti,則有
t (n
)=∑i
=18t
ic
it(n)=\sum_^8 t_ic_i
t(n)=∑
i=18
ti
ci分析例項
作者進行了很仔細的分析,略.總之,輸入規模定為序列的長度n.
如果輸入序列一開始就排好了序,那麼t(n
)t(n)
t(n)
會取到最小值,這是最好的情況.
大概類似t(n
)=(c
1+c2
+c4+
c5+c
8)n−
(c2+
c4+c
5+c8
)t(n)=(c_1+c_2+c_4+c_5+c_8)n-(c_2+c_4+c_5+c_8)
t(n)=(
c1+
c2+
c4+
c5+
c8)
n−(c
2+c
4+c
5+c
8)
顯然,t(n
)t(n)
t(n)
是關於n的線性函式.
如果輸入序列是反向排序的,即最糟情況,那麼t(n
)t(n)
t(n)
會得到最大值.
乙個很複雜的式子,會得到t(n
)t(n)
t(n)
是關於n的二次函式.
在這裡,作者指出,算衡量執行時間的好壞,並非是看最好情況和最壞情況如何折中,而是僅僅看最差時間.
因為很多情況中,非最好情況的時間和最壞情況沒什麼區別.
增長量級
相比具體的執行時間,更值得關注的是,演算法如何隨輸入規模的增長而增長.
為此,在公式t(n)中,進一步忽視掉每條語句的常量c
ic_i
ci,和n的非最高端項.這樣得到的純粹的n的最高次項.
這樣,我們就可以得到最壞情況下執行時間可以表示為θ(n
2)
\theta(n^2)
θ(n2).
不同的增長量級,在n的規模足夠大的情況下,總能進行絕對的比較.
演算法導論 插入排序
introduction to algorithms second edition chapter2,insertion sort date 2014 9 14 include include include define max 50 typedef struct sortarr 直接插入排序 i...
演算法導論 插入排序
插入排序應該算是比較好理解的一種了,原理類似於我們打牌的時候,摸牌插入手中的情景。來看一下圖,立刻就明白了 我們將乙個陣列int a 12 看做一副撲克牌,假設陣列有12個數,那麼撲克牌也一共有十二張,放在一起開始 我們先抽一張拿到手上,這時候,我們不需要排序,因為不論哪一張先被我們抽上來,不論大小...
演算法導論 插入排序
對於只有乙個元素的陣列,本身為已序。對於兩個元素的a,認為 a0 為已序,a1為key 若key a0 則將key 放到a0後。若不是,後移a0 對於多個元素的陣列 考慮將key 插入到已序的 a0 aj a0 a1 a2.中,可以將key 與aj a0 逐個比較,並後移,直到遇到乙個比key 小的...