1. 程式人生 > >資料結構和演算法分析之排序篇--歸併排序(Merge Sort)和常用排序演算法時間複雜度比較(附贈記憶方法)

資料結構和演算法分析之排序篇--歸併排序(Merge Sort)和常用排序演算法時間複雜度比較(附贈記憶方法)

歸併排序的基本思想

歸併排序法是將兩個或以上的有序表合併成一個新的有序表,即把待排序序列分成若干個子序列,每個子序列是有序的。然後再把有序子序列合併為整體有序序列。注意:一定要是有序序列!
歸併排序例項:
這裡寫圖片描述

合併方法:

設r[i……n]由兩個有序子表r[i….m]和r[m+1……n]組成,兩個子表長度分別為m-i+1、n-m。
1. J=m+1 ;k=i ; I=i ; 置兩個子表的起始下標及輔助陣列的起始下標;
2. 若I>m 或J>n ,轉(4),表示其中一個子表已合併完,比較選取結束;
3. //選取r[i]和r[j]較小的存入輔助陣列rf
如果r[i] < r[j],rf[k]=r[i]; i++; k++; 轉⑵
否則,rf[k]=r[j]; j++; k++; 轉⑵
4.//選取r[i]和r[j]較小的存入輔助陣列rf
如果r[i] < r[j],rf[k]=r[i]; i++; k++; 轉⑵
否則,rf[k]=r[j]; j++; k++; 轉⑵
5.合併結束

void Merge(ElemType *r,ElemType *rf, int i, int m, int n)  
{  
    int j,k;  
    for(j=m+1,k=i; i<=m && j <=n ; ++k){  
        if(r[j] < r[i]) rf[k] = r[j++];  
        else rf[k] = r[i++];  
    }  
    while(i <= m)  rf[k++] = r[i++];  
    while(j <= n)  rf[k++] = r[j++];  
}

時間複雜度–歸併排序

歸併的時間複雜度分析:主要考慮兩個函式的時間花銷,一、陣列劃分函式 二、有序陣列歸併函式
前者的時間複雜度為O(n),因為程式碼中有2個長度為n的迴圈,所以時間複雜度為O(n);
陣列長度為n的歸併排序所消耗的時間T[n]:呼叫前面函式將陣列劃分為兩個部分,那每一個部分排序好所花時間為T[n/2],最後將這兩個部分的數組合併成一個有序陣列的時間花費為O(n);

公式:T[n]=2T[n/2]+O(n);

最終得出結果為:T[n]=O(nlogn);
因為不管元素在什麼情況下都要做出這些步驟,所花銷的時間是不變的,所以該演算法的最優時間複雜度和最差時間複雜度以及平均複雜度是一致的:O(nlogn)

歸併排序的總結

  1. 歸併排序是對幾個有序表有序表的排序,合併成一個新的有序表,若拿到的序列是一個亂序的序列,則需要對此序列進行分割,分割成若干個有序的數列再進行排序合併。
  2. 歸併排序程式碼實現起來主要用到的是兩個指標,i, j . 每當指標對應的數被選擇放入新陣列中時,需要向後指一位。

常用排序演算法時間複雜度分析

不穩定的排序演算法:選擇排序、快速排序、希爾排序、堆排序;
穩定的排序演算法: 氣泡排序,直接插入排序、歸併排序等。。。

這裡寫圖片描述

關於穩定性的記憶方法:
1、插入排序和交換排序各自的初始排序方式,也就是直接插入排序和氣泡排序都是穩定的排序。歸併排序是優化排序方式中唯一一種穩定的排序方式。
2、希爾排序和快速排序是插入排序和交換排序的優化方式中的,不穩定的排序方式。
3、選擇排序和堆排序是具有共同性質,就是不穩定性。

附錄:
什麼叫穩定性:通俗地講就是能保證排序前2個相等的數其序列的前後位置順序和排序後他們兩個的前後位置順序相同。在簡單形式化一下,如果Ai=Aj,Ai原來在位置前,排序後Ai還是要在Aj位置前。

穩定性的好處:排序演算法如果穩定,那麼從一個鍵上排序,然後再從另一個鍵上排序,第一個鍵排序的結果可以為第二個鍵排序所用。

注意區分選擇排序和堆排序的關係:
選擇排序:基本思想就是依次從待排序中選擇關鍵字最小的記錄、次小的記錄。。。。。並分別將他們定位到序列左側的第一個位置,第二個位置。。。,從而使得序列是從小到大排序的序列。

直接選擇排序:從第i個無序列表arr[i…n]中,選擇關鍵字值最小的記錄將其插入有序列表的末尾arr[n-i+1],交換一次位置。–是不穩定排序。
堆排序:滿足完全二叉樹特性,其左右子樹分別是堆,任何一個結點的值不大於或不小於左右孩子結點的值;堆排序分別稱為小頂堆和大頂堆。

關於時間複雜度的記憶方法:
1、初始排序方式時間複雜度基本上都是O(n^2),其中包括插入排序,氣泡排序,選擇排序注意氣泡排序和插入排序的最好時間複雜度為O(n);
2、優化的排序方式的時間複雜度基本上都是O(nlogn),其中包括快速排序,堆排序和歸併排序。注意快速排序的最壞情況類似於氣泡排序,因此時間複雜度為O(n^2);
3、希爾排序是個特例,無法計算它的時間複雜度,因為與增量因子序列dk的選取有關。