交換類排序

2021-05-27 07:25:03 字數 3533 閱讀 3232

交換排序

交換排序主要是根據記錄的關鍵字的大小,將記錄交換來進行排序的。交換排序的特點是:將關鍵字值較大的記錄向序列的後部移動,關鍵字較小的記錄向前移動。這裡介紹兩種交換排序方法,它們是氣泡排序和快速排序。

氣泡排序

將被排序的記錄陣列r[1..n]垂直排列,每個記錄r[i]看作是重量為r[i].key的氣泡。根據輕氣泡不能在重氣泡之下的原則,從下往上掃瞄陣列r:凡掃瞄到違反本原則的輕氣泡,就使其向上"飄浮"。如此反覆進行,直到最後任何兩個氣泡都是輕者在上,重者在下為止。

1.演算法思路

(1)讓j取n至2,將r[j].key與r[j-1].key比較,如果r[j].key

【例】 設有一組關鍵字序列{ 55 , 22 , 44 , 11 , 33 },這裡 n=5 ,即有 5 個記錄。請將其按由小到大的順序排序。 如圖9.3

2.具體演算法

/*氣泡排序,時間複雜度為o(n2),穩定排序,適合規模比較小的*/

for(i=0; i

void bubble_sort(int array,int n)

}}

3.演算法時間複雜度

該演算法的時間複雜度為o(n2)。但是,當原始關鍵字序列已有序時,只進行一趟比較就結束,此時時間複雜度為o(n)。

1、演算法思想

快速排序是c.r.a.hoare於2023年提出的一種劃分交換排序。它採用了一種分治的策略,通常稱其為分治法(divide-and-conquermethod)。

(1) 分治法的基本思想

分治法的基本思想是:將原問題分解為若干個規模更小但結構與原問題相似的子問題。遞迴地解這些子問題,然後將這些子問題的解組合為原問題的解。

(2)快速排序的基本思想

設當前待排序的無序區為r[low..high],利用分治法可將快速排序的基本思想描述為:

①分解:

在r[low..high]中任選乙個記錄作為基準(pivot),以此基準將當前無序區劃分為左、右兩個較小的子區間r[low..pivotpos-1)和r[pivotpos+1..high],並使左邊子區間中所有記錄的關鍵字均小於等於基準記錄(不妨記為pivot)的關鍵字pivot.key,右邊的子區間中所有記錄的關鍵字均大於等於pivot.key,而基準記錄pivot則位於正確的位置(pivotpos)上,它無須參加後續的排序。

注意:  劃分的關鍵是要求出基準記錄所在的位置pivotpos。劃分的結果可以簡單地表示為(注意pivot=r[pivotpos]):

r[low..pivotpos-1].keys≤r[pivotpos].key≤r[pivotpos+1..high].keys

其中low≤pivotpos≤high。

②求解:

通過遞迴呼叫快速排序對左、右子區間r[low..pivotpos-1]和r[pivotpos+1..high]快速排序。

③組合:

因為當"求解"步驟中的兩個遞迴呼叫結束時,其左、右兩個子區間已有序。對快速排序而言,"組合"步驟無須做什麼,可看作是空操作。

2、快速排序演算法quicksort

void quicksort(seqlist r,int low,int high)

//endwhile

r[i]=pivot; //基準記錄已被最後定位

return i;

} //partition

4、演算法分析

快速排序的時間主要耗費在劃分操作上,對長度為k的區間進行劃分,共需k-1次關鍵字的比較。

(1)最壞時間複雜度

最壞情況是每次劃分選取的基準都是當前無序區中關鍵字最小(或最大)的記錄,劃分的結果是基準左邊的子區間為空(或右邊的子區間為空),而劃分所得的另乙個非空的子區間中記錄數目,僅僅比劃分前的無序區中記錄個數減少乙個。

因此,快速排序必須做n-1次劃分,第i次劃分開始時區間長度為n-i+1,所需的比較次數為n-i(1≤i≤n-1),故總的比較次數達到最大值:

cmax = n(n-1)/2=o(n2)

如果按上面給出的劃分演算法,每次取當前無序區的第1個記錄為基準,那麼當檔案的記錄已按遞增序(或遞減序)排列時,每次劃分所取的基準就是當前無序區中關鍵字最小(或最大)的記錄,則快速排序所需的比較次數反而最多。

(2) 最好時間複雜度

在最好情況下,每次劃分所取的基準都是當前無序區的"中值"記錄,劃分的結果是基準的左、右兩個無序子區間的長度大致相等。總的關鍵字比較次數:

0(nlgn)

注意:  用遞迴樹來分析最好情況下的比較次數更簡單。因為每次劃分後左、右子區間長度大致相等,故遞迴樹的高度為o(lgn),而遞迴樹每一層上各結點所對應的劃分過程中所需要的關鍵字比較次數總和不超過n,故整個排序過程所需要的關鍵字比較總次數c(n)=o(nlgn)。

因為快速排序的記錄移動次數不大於比較的次數,所以快速排序的最壞時間複雜度應為0(n2),最好時間複雜度為o(nlgn)。

(3)基準關鍵字的選取

在當前無序區中選取劃分的基準關鍵字是決定演算法效能的關鍵。

①"三者取中"的規則

"三者取中"規則,即在當前區間裡,將該區間首、尾和中間位置上的關鍵字比較,取三者之中值所對應的記錄作為基準,在劃分開始前將該基準記錄和該區伺的第1個記錄進行交換,此後的劃分過程與上面所給的partition演算法完全相同。

②取位於low和high之間的隨機數k(low≤k≤high),用r[k]作為基準

選取基準最好的方法是用乙個隨機函式產生乙個取位於low和high之間的隨機數k(low≤k≤high),用r[k]作為基準,這相當於強迫r[low..high]中的記錄是隨機分布的。用此方法所得到的快速排序一般稱為隨機的快速排序。具體演算法【參見教材】

注意: 隨機化的快速排序與一般的快速排序演算法差別很小。但隨機化後,演算法的效能大大地提高了,尤其是對初始有序的檔案,一般不可能導致最壞情況的發生。演算法的隨機化不僅僅適用於快速排序,也適用於其它需要資料隨機分布的演算法。

(4)平均時間複雜度

儘管快速排序的最壞時間為o(n2),但就平均效能而言,它是基於關鍵字比較的內部排序演算法中速度最快者,快速排序亦因此而得名。它的平均時間複雜度為o(nlgn)。

(5)空間複雜度

快速排序在系統內部需要乙個棧來實現遞迴。若每次劃分較為均勻,則其遞迴樹的高度為o(lgn),故遞迴後需棧空間為o(lgn)。最壞情況下,遞迴樹的高度為o(n),所需的棧空間為o(n)。

(6)穩定性

快速排序是非穩定的,例如[2,2,1]。

排序 交換類排序

演算法思想 陣列中第乙個元素和第二個元素比較,按照規則進行交換,再讓第二個和第三個進行比較,直到最大或最小的那個數交換到最後,一趟氣泡排序完成。以公升序為例,氣泡排序主要是讓大的下沉,小的上浮,每一趟排序確立乙個當前無序序列中最大的那個數,使之下沉。時間複雜度分析 最壞 整個陣列逆序,最內層迴圈的語...

排序演算法 交換類排序

今天我們討論一下交換類排序。交換排序的演算法思想 通過交換逆序的元素實現交換排序。交換排序主要有兩種 一種是氣泡排序,一種是快速排序。演算法思想 氣泡排序是一種簡單的交換類排序演算法,它是通過交換相鄰兩個資料元素,逐步將排序序列變成有序序列。基本演算法思想描述如下 假設待排序元素有n個,從第乙個元素...

排序(二)交換類排序

繼前面的氣泡排序,今天重點是快速排序 快速排序是基於分治法 先講一下分治法,分治法官方定義 首先將原問題分解成若干個子問題,這個子問題只是原問題較小規模的例項。解決這些子問題,遞迴的求解各個子問題。遞迴的邊界就是問題規模足夠小時,可以直接求解。那和快速排序有什麼關係呢?快速排序原理 找乙個樞軸 一般...