4 內部排序 歸併排序

2021-06-29 13:33:54 字數 2468 閱讀 4264

歸併排序

歸併排序和快速排序這兩種演算法都採用了分治的思想,且速度僅次於

快速排序

,為穩定排序演算法,一般用於對總體無序,但是各子項相對有序的

數列,其具體思想如下:

1、將序列每相鄰兩個數字進行歸併操作(merge),形成(n/2)個序列,排序後每個序列包含兩個元素;

2、將上述序列再次歸併操作,形成(n/4)個序列,每個序列包含四個元素;

3、重複步驟2,直到所有元素排序完畢。

歸併排序中一般所用到的是2-路歸併排序,即將含有n個元素的序列看成是n個有序的子串行,每個子串行的長度為1,而後兩兩合併,得到n/2個長度為2或1的有序子串行,再進行兩兩合併……直到最後由兩個有序的子串行合併成為乙個長度為n的有序序列。2-路歸併的核心操作是將一維陣列中前後相鄰的兩個有序序列歸併為乙個有序序列。

1、一般歸併排序

實現**

如下:

public class mergesort 

// 將arr序列中剩餘的元素複製到brr中,這兩個語句只可能執行其中乙個

while (i <= mid)

brr[k++] = arr[i++];

while (j <= end)

brr[k++] = arr[j++];

// 將brr中的元素複製到arr中,使arr[start,...,end]有序

for (i = 0; i < k; i++)

arr[i + start] = brr[i];

} /*

* 借助brr陣列對arr[start,...,end]內的元素進行歸併排序,歸併排序後的順序為從小到大

*/public static int mergesort(int arr, int brr, int start, int end)

return arr;

} public static void print(int array)

} public static void main(string args) ;

int len = arr.length;

int brr = new int[len];

print(mergesort.mergesort(arr, brr, 0, len - 1));

}}

總結:時間複雜度為o(nlogn),這是該演算法中最好、最壞和平均的時間效能。

空間複雜度為 o(n)。

歸併排序比較占用記憶體,但卻是幾個高效排序演算法(快速排序、希爾排序、堆排序)中唯一穩定的排序方法。

2、原地歸併排序

上面的歸併排序需要乙個臨時陣列brr來存放歸併後的陣列arr,然後將brr複製到arr中,空間複雜度為o(n),下面介紹一種時間複雜度為o(1)的原地歸併排序。

原地歸併排序,就是

用「手搖演算法」把歸併排序的歸併過程中使用到的輔助陣列去掉,將空間複雜度降為o(1)。

「手搖演算法」

首先,我們來看乙個有趣的小演算法:手搖演算法(也叫三次反轉演算法)。

題目:將字串abcdefg,變成efgabcd,要求空間複雜度o(1)。

解答:第一步:將子串abcd反轉,變成dcba。源字串變成dcbaefg

第二步:將字串efg反轉,變成gfe。源字串變成dcbagfe

第三步:將整個字串dcbagfe反轉,變成efgabcd。

手搖演算法常常被用來旋轉字串,一定要記住這個小演算法。下面,我們來看看怎樣用手搖演算法,實現原地歸併排序。

舉例:

1.原始序列如圖a, i到j-1為第乙個序列(記為序列1),j到序列尾為第二個序列(記為序列2),我們要把兩個有序序列合併成乙個有序的序列

2.圖a中因為i.data < j.data,所以i++,直到i.data>j.data,

如圖b3.另index記下此時j的位置,j向後掃瞄,直到j.data>i.data為止,如圖c

4.此時我們看到序列1,i之前的元素,都小於序列2,j之前的元素到小於[i,index)的元素。

5.將圖d中藍色部分和紅色部分用手搖演算法翻轉。翻轉後,結果如下圖e:

6.然後將i移動j-index步,如圖f。重複上述步驟,即可完成兩個有序序列的合併了。

實現**:

內部排序演算法4(歸併排序)

將兩個有序表合成乙個新的有序表就是二路歸併。例如,在元素序列l中有兩個已經排好序的有序順序表l left l mid 和l m id 1 l righ t 它們可以歸併成為乙個有序表,仍然存放於l left l righ t 中。在歸併排序中,用變數 i 和 j分別做 l 中兩個表的當前檢測指標,用...

內部排序(四)歸併排序

總述 歸併排序 merging sort 中歸併是將兩個或兩個以上的有序表組合成乙個新的有序表。歸併排序我們主要 2 路歸併排序。2 路歸併排序 過程 假設初始序列含有n個記錄,則可看成是n個有序的子串行,每個子串行的長度為1,然後兩兩歸併,得到ceil n 2 個長度為2或1的有序子串行 再兩兩歸...

內部排序之歸併排序

1.歸併排序 歸併排序,顧名思義就是將兩個序列合併到一起,並且使之有序。該演算法是分治法的乙個典型應用,其主要思想是將已有序的兩個子串行合併,在這個過程中,對其元素進行比較排序,從而得到乙個完整的有序的序列。也就是先要保證小範圍的資料有序,再使大範圍的序列有序。因此,若要使用歸併排序對乙個序列進行排...