數據結構導論之第七章排序

1、概念

數據排序 :排序就是將一組對象按照規定的次序從新排列的過程,排序每每是爲檢索服務的。算法

穩定排序 :若排序後,相同關鍵字的記錄保持它們原來的相對次序,則此排序方法稱爲穩定排序;穩定性是排序方法自己的特性,與數據無關。數組

排序類型:性能

  • 內部排序: 所有數據存於內存;
  • 外部排序: 須要對外存進行訪問的排序過程

內部排序 按方法分測試

  • 插入排序
  • 交換排序
  • 選擇排序
  • 歸併排序

排序指標(排序算法性能分析):ui

  • 存儲空間
  • 比較次數

2、插入排序

經常使用的插入排序方法有直接插入排序折半插入排序表插入排序希爾排序spa

直接插入排序(Straight Insertion Sorting)是一種簡單的排序方法,它的基本思想是依次將每一個記錄插入到一個已排好序的有序表中去,從而獲得一個新的、記錄數增長 1 的有序表。直接插入排序相似圖書館中整理圖書的過程。code

// R 待排序的表  n是表長
void StraightlnsertSort(List R,int n){ 
    int i,j; 
    for (i=2;i<=n;i++){ 
        R[0]=R[i];//第 i 個記錄複製爲崗哨
        j=i-1;
        while (R[0].key<R[j].key){ //與崗哨比較,直至鍵值不大於崗哨鍵值
            R[j+1]=R[j]; //將第 j 個記錄賦值給第 j+1 個記錄
            j--; 
        }
        R[j+1]=R[0]; //將第 i 個記錄插入到序列中
    }
}

記錄 R[0]有兩個做用,其一是進入查找循環以前,它保存了 R[i]的值,使得不致於因 記錄的後移而丟失 R[i]中的內容;其二是起崗哨做用,在 while 循環中「監視」數組下標 變量 j 是否越界,一旦越界(即 j<1), R[0]自動控制 while 循環的結束,從而避免了在 while 循環中每一次都要檢測 j 是否越界。這一技巧的應用,使得測試循環條件的時間大 約減小一半。對象

算法分析:直接插入排序的算法簡單,易於理解,容易實現,時間複雜度爲 O(n2 ),若待排序記錄 的數量很大時,通常不選用直接插入排序。從空間來看,它只須要一個記錄的輔助空間,即 空間複雜度爲 O(1)。 直接插入排序方法是穩定的。blog

●存儲空間 n+1;(1爲附加空間),空間複雜度 O(1)
●時間複雜度 O(n 2 ) ,若是給出的待排序表是順序的,則時間複雜度最好 O(n)
●穩定性:穩定排序;排序

3、交換排序

交換排序的基本思想:比較兩個記錄鍵值的大小,若是這兩個記錄鍵值的大小出現逆 序,則交換這兩個記錄,這樣將鍵值較小的記錄向序列前部移動,鍵值較大的記錄向序列 後部移動。

交換排序包括:冒泡排序和快速排序。

一、冒泡排序:

基本思想: 經過屢次重複比較、交換相鄰記錄而實現排序;每一趟的效果都是將當前鍵值最大的記錄換到最後

在算法實現時,定義一個整型變量 endsort,在每一次排序以前,先將它置爲 0,若 在一趟起泡中交換了記錄,則將它置爲 1。當一次循環結束時,咱們再檢查 endsort,若 endsort 的值爲 0 便終止算法。

// R 待排序的表  n是表長
void BubbleSort(List R,int n){
    /*endsort:標誌文件是否已排好序*/
    for( i=1; i<=n-1; i++ ){ 
        endsort=0; /*若循環中記錄未做交換,則說明序列已有序*/
        for( j=1; j<=n-i-1; j++ ){
            if( R[j].key > R[j+1].key ){
                temp=R[j]; 
                R[j]=R[j+1]; 
                R[j+1]=temp;
                endsort=1;
            }
        }
        if(endsort==0) break;
    }
}
  • 時間複雜度: O(n2 ) 、若是是排好序的表 O(n)
  • 空間複雜度 :O(1)
  • 穩定性:穩定排序。

二、快速排序(Quick Sorting)是交換排序的一種,實質上是對冒泡排序的一種改進;首先取第一個記錄,將之與表中其他記錄比較並交換,從而將它放到記錄的正確的最終位置,使記錄表分紅兩部分{其一(左邊的)諸記錄的關鍵字均小於它;其二(右邊的)諸記錄的關鍵字均大於它};而後對這兩部分從新執行上述過程,依此類推,直至排序完畢

 

算法分析:

  • ●空間:n+log 2 n; (log 2 n爲附加空間—棧)
  • ●時間:O(nlog 2 n)注:若初始記錄表有序或基本有序,則快速排序將蛻化爲冒泡排序,其時間複雜度爲O(n 2 );即:快速排序在表基本有序時,最不利於其發揮效率。
  • ●穩定性:不穩定排序

 4、選擇排序

選擇排序(Selection Sorting)的基本思想:每一次在 n-i+1(i=1,2,…,n-1)個記錄中 選取鍵值最小的記錄做爲有序序列的第 i 個記錄。

分類:直接選擇排序和堆排序

 1.直接選擇排序

直接選擇排序算法的基本思想:在第 i 次選擇操做中,經過 n-i 次鍵值間比較,從 n-i+1個記錄中選出鍵值最小的記錄,並和第 i(1≤i≤n-l)個記錄交換。

void SelectSort (List R,int n){ 
    int min,i,j;
     //每次循環,選擇出一個最小鍵值
    for(i=1;i<=n-1;i++){ 
        min=i; //假設第 i 個記錄鍵值最小
        for (j=i+1;j<=n;j++){
            if (R[j].key<R[min].key){
                min=j;//記錄下鍵值較小記錄的下標
            } 
            if (min!=i){
                swap(R[min],R[i]); //將最小鍵值記錄和交換第 i 個記錄交換
            } 
        }
    }
}

算法分析:

  • ●空間:n+1; (1爲附加空間)
  • ●時間:O(n 2 ) ,不適宜於 n 較大的狀況
  • ●穩定性:不穩定排序

二、堆排序

建堆(篩選法):
1)方法:
設記錄{ R 1 , R 2 , …., R n }
(1)順序輸入成徹底二叉樹(以數組存儲)
(2)從最後一個雙親開始,若是有較小的孩子,則將其沿左或右孩中小的那個方向篩下,一直到不能再篩;
(3)逐次處理完每一個雙親。

在堆排序中,對於 n 個記錄進行序所需的平均時間是 O(nlog2n)。在最壞狀況下,其 時間複雜度也爲 O(nlog2n)。相對於快速排序來講,這是堆排序的最大優勢。此外,堆排序 僅需一個記錄大小的供交換用的輔助存儲空間。 堆排序是不穩定的。

5、歸併排序 

歸併排序(Merge Sorting)是與插入排序、交換排序、選擇排序不一樣的一類排序方法,其不 同之處在於要求待排序列是由若干個有序子序列組成。歸併的含義是將兩個或兩個以上的有 序表合併成一個新的有序表。合併的方法是比較各子序列的第一個記錄的鍵值,最小的一個 就是排序後序列的第一個記錄的鍵值。取出這個記錄,繼續比較各子序列現有的第一個記錄 的鍵值,即可找出排岸後的第二個記錄。如此繼續下去,最終能夠獲得排序結果。 所以歸併排序的基礎是合併。

分類:

 

  • 有序序列的合併
  • 二路歸併排序

 歸併排序算法的時間複雜度爲 O(nlog2n),因爲要用到和待排記錄等數量的數組 b 來存放結 果,因此實現歸併排序須要附加一倍的存儲開銷。二路歸併排序是穩定的。 在 n 較大時,歸併排序的時間性能優於堆排序,但它所需的輔助存儲量較多。O(n)

 

相關文章
相關標籤/搜索