算法基礎(chǔ)(一)
時間:2016-12-14作者:華清遠(yuǎn)見
排序: 我們?yōu)楹我芯颗判颍?br/>
1. 有時候應(yīng)用程序本身需要對信息進(jìn)行排序。 我們之前已經(jīng)學(xué)過簡單排序法和冒泡排序法。接下來我們介紹一下插入排序和合并排序。 插入排序的機(jī)制和打牌時整理手中的牌做法差不多。摸牌的時候,需要將摸到的牌插入到手中一把牌中的正確的位置上。為了要找到這張牌的位置,我們需要將它與手中每張牌從右到左進(jìn)行比較。無論何時,左手中的牌都是排好序的。 這個算法中,所有的元素都是原地排序(sorted in place),就意味著這些數(shù)字就是在數(shù)組本身中重新排序的。 算法如下: 偽代碼: 代碼(c語言實(shí)現(xiàn)):
//a 是一個數(shù)組,size_a是這個數(shù)組的元素個數(shù) 插入排序算法的時間復(fù)雜度是O(n 2 ) 。當(dāng)然算法的執(zhí)行速度,和n的大小(輸入規(guī)模)以及樣本的結(jié)構(gòu)有關(guān)系。考慮壞的情況,就是輸入的n個數(shù)為逆序排列,此時插入排序算法,隨著n的增大,運(yùn)算時間的增長與 n 2 同數(shù)量級。 2.分治法策略 分解(divide):講原有問題分解成為一系列子問題; 合并排序 merge過程的代價是O(n)。其中n = r - p + 1是待合并的元素個數(shù)。 為了能檢查兩個子數(shù)組是否是空,其想法是在每一個數(shù)組底部放一個“哨兵”,它包含了特殊值,用于簡化代碼。
具體來說,merge過程是這樣工作的:第一行計算子數(shù)組a[p...q]的長度n1,第二行計算子數(shù)組a[q+1...r]的長度n2.在第三行中,創(chuàng)建了數(shù)組L和R,長度各位n1 +1,n2 + 1.第四到第五行中的for循環(huán)將子數(shù)組a[p...q]復(fù)制到L[1....n1]中去。 第六到第七行中的for循環(huán)將子數(shù)組a[q+1...r]復(fù)制到R[1....n2]中去。第八九行講哨兵置于L和R的末尾。第十到第十七行,是合并的具體過程。通過比較,將兩子數(shù)組按照從小到大的方式合并,存入數(shù)組A中。 c語言描述如下所示 void merge( int * a, int p, int q, int r){ 合并merge過程就可以作為合并排序中的一個子程序來使用。偽代碼如下:
c語言描述過程為: void merge_sort( int * a, int p, int r){ 合并程序的具體圖示:
關(guān)于分治法排序的簡要分析:
我們將一個規(guī)模為n的問題,拆分成n個規(guī)模為1的子問題。拆分的過程經(jīng)歷了 lg n + 1層,在合并時,每一層的問題規(guī)模為n,則總代價為O (n * lg n + n ) ,忽略低階項(xiàng)和常數(shù)項(xiàng),因此合并排序法的時間復(fù)雜度為O(n lg n )。 接下來會介紹一下堆排序和快速排序。以上的所有排序方法,都是比較排序。也就是說,他們通過對數(shù)組元素比較來實(shí)現(xiàn)排序。比較排序法是有極限的,從壞的輸入情況,比較排序法的時間復(fù)雜度是 O(n lg n )。我們介紹的合并排序以及快速排序,都是漸進(jìn)優(yōu)的比較排序方式。我們還會介紹可以突破比較排序極限的排序方式——計數(shù)排序。
相關(guān)資訊
發(fā)表評論
|
學(xué)院新動態(tài)