歸併,快速,堆排序

2022-05-15 23:53:35 字數 2556 閱讀 7617

堆排序

堆排序利用了大根堆(或小根堆)堆頂記錄的關鍵字最大(或最小)這一特徵,使得在當前無序區中選取最大(或最小)關鍵字的記錄變得簡單。

(1)用大根堆排序的基本思想

① 先將初始檔案r[1..n]建成乙個大根堆,此堆為初始的無序區

② 再將關鍵字最大的記錄r[1](即堆頂)和無序區的最後乙個記錄r[n]交換,由此得到新的無序區r[1..n-1]和有序區r[n],且滿足r[1..n-1].keys≤r[n].key

③由於交換後新的根r[1]可能違反堆性質,故應將當前無序區r[1..n-1]調整為堆。然後再次將r[1..n-1]中關鍵字最大的記錄r[1]和該區間的最後乙個記錄r[n-1]交換,由此得到新的無序區r[1..n-2]和有序區r[n-1..n],且仍滿足關係r[1..n-2].keys≤r[n-1..n].keys,同樣要將r[1..n-2]調整為堆。

直到無序區只有乙個元素為止。

(2)大根堆排序演算法的基本操作:

① 初始化操作:將r[1..n]構造為初始堆;

② 每一趟排序的基本操作:將當前無序區的堆頂記錄r[1]和該區間的最後乙個記錄交換,然後將新的無序區調整為堆(亦稱重建堆)。

注意:①只需做n-1趟排序,選出較大的n-1個關鍵字即可以使得檔案遞增有序。

②用小根堆排序與利用大根堆類似,只不過其排序結果是遞減有序的。堆排序和直接選擇排序相反:在任何時刻堆排序中無序區總是在有序區之前,且有序區是在原向量的尾部由後往前逐步擴大至整個向量為止

堆排序的最壞時間複雜度為o(nlogn)。堆序的平均效能較接近於最壞效能。

不穩定的排序演算法

**view code

1

void adjust(int i,int n)//

調整為小頂堆216

else

17break;18

}19 a[i] = a[0];//

放在合適位置20}

21void heapsort(int

n)22

33 }

快速排序

設要排序的陣列是a[0]……a[n-1],首先任意選取乙個資料(通常選用第乙個資料)作為關鍵資料,然後將所有比它小的數都放到它前面,所有比它大的數都放到它後面,這個過程稱為一趟快速排序。值得注意的是,快速排序不是一種穩定的排序演算法,也就是說,多個相同的值的相對位置也許會在演算法結束時產生變動。

最壞 時間複雜度為o(n2)。

最佳 t(n)=θ(nlogn)

**view code

1/*2

一趟快速排序的演算法是:   

3找乙個記錄,以它的關鍵字作為「樞軸」,

4凡其關鍵字小於樞軸的記錄均移動至該記錄之前,

5反之,凡關鍵字大於樞軸的記錄均移動至該記錄之後。

6a[0] a[1] a[2] a[3] a[4] a[5] a[6]:   

749 38 65 97 76 13 27   

8進行第一次交換後:

927 38 65 97 76 13 49   

10進行第二次交換後:

1127 38 49 97 76 13 65   

12進行第三次交換後:27 38 13 97 76 49 65    

13進行第四次交換後:27 38 13 49 76 97 65

14*/

15int fqsort(int low,int high,int

a)16

27 a[i] =k;

28return j;//

j左右兩邊已經被k分割開 再把j+1當作右邊一組的low j-1當作左邊一組的high進行下一次的快排29}

30void qsort(int low,int high,int

a)31

39 }

歸併排序

歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法(divide and conquer)的乙個非常典型的應用。

將已有序的子串行合併,得到完全有序的序列;即先使每個子串行有序,再使子串行段間有序。若將兩個有序表合併成乙個有序表,稱為2-路歸併。

歸併排序是穩定的排序.即相等的元素的順序不會改變.如輸入記錄 1(1) 3(2) 2(3) 2(4) 5(5) (括號中是記錄的關鍵字)時輸出的 1(1)

2(3) 2(4) 3(2) 5(5) 中的2 和 2

是按輸入的順序.這對要排序資料報含多個資訊而要按其中的某乙個資訊排序,要求其它資訊盡量按輸入的順序排列時很重要.這也是它比快速排序優勢的地方.

**view code

1

void msort(int low,int mid,int high)//

將兩部分歸併219

while(i<=n1)

20 a[k++] = x[i++];

21while(j<=n2)

22 a[k++] = y[j++];23}

24void merge(int low,int high)//

二分遞迴合併

2534 }

快速排序 堆排序 歸併排序

快速排序 includeusing namespace std int a 8 int sz sizeof a sizeof int int partition int a,int p,int r int main const int sz sizeof a sizeof int 堆化 保持最大堆的...

快速排序,歸併排序,堆排序

l r 1在奇數長度陣列的中間,偶數長度陣列的左半邊最後乙個,極限情況下陣列只有兩個數,i遇到第乙個數就會停下,此時模擬i,j下標的數有無交換的情況,會發現j在停下來時都位於第乙個數的位置,因此用j,j 1才不會越界 l r 1 1在奇數長度陣列的中間往右第乙個,偶數長度陣列的右半邊第乙個,極限情況...

關於快速排序,歸併排序,堆排序

1 快速排序 quicksort 快速排序是乙個就地排序,分而治之,大規模遞迴的演算法。從本質上來說,它是歸併排序的就地版本。快速排序可以由下面四步組成。1 如果不多於1個資料,直接返回。2 一般選擇序列最左邊的值作為支點資料。3 將序列分成2部分,一部分都大於支點資料,另外一部分都小於支點資料。4...