排序算法之歸併排序

歸併排序也是效率較高的排序算法之一。其核心思想就是將兩個已經排好序的序列合併成一個有序的序列。所以整個算法分成兩部分,第一部分是分割,將一個長的無序的序列分解許多成只包含一個元素的序列。例如將序列:{12, 23, 8, 42, 15, 21}分解成{12},{23},{8},{42},{15},{21} 。第二部分是將分解好的序列進行歸併。即先將序列歸併成{12, 23},{8, 42},{15, 21},然後繼續歸併成{8, 12, 23, 42},{15, 21},最後得到結果{8, 12, 15, 21, 23, 42} 。
下面是代碼(以升序爲例):

void mergeSort(int unsort[], int start, int end){
    int length = end - start + 1, mid = (end + start)/2;
    if(length <= 1)
        return;
    //分割
    mergeSort (unsort, start, mid);
    mergeSort (unsort, mid + 1, end);

    //排序
    //只有兩個元素時,直接在unsort的基礎上進行交換元素即可
    if(length == 2){
        if(unsort[start] > unsort[end]){
            int temp = unsort[start];
            unsort[start] = unsort[end];
            unsort[end] = temp;
        }
        return ;
    }
    //有多個元素時,需要將兩個序列進行歸併,由於兩個序列都是有序的,所以歸併時可以不需要回溯直接沿着一個方向進行。
    int i = start, j = mid + 1, k = 0;
    int* temp = new int[length];

    while(i <= mid && j <= end){
        if(unsort[i] < unsort[j])
            temp[k++] = unsort[i++];
        else
            temp[k++] = unsort[j++];
    }

    while(i <= mid)
        temp[k++] = unsort[i++];

    while(j <= end)
        temp[k++] = unsort[j++];
    //將temp數組中的數值複製到unsort中
    i = start;
    j = 0;
    while(j < length){
        unsort[i++] = temp[j++];
    }
}

從上面的代碼我們可以看出每次歸併操作的時間複雜度都是O(n),將序列分解的時間複雜度是O(log(n)), 所以總的時間複雜度是O(n log(n)) 。

点赞