1. 程式人生 > 實用技巧 >合併(歸併)排序

合併(歸併)排序

合併排序

合併排序(Merge Sort)演算法就是將多個有序資料表合併成一個有序資料表。如果參與合併的只有兩個有序表,則稱為二路合併。對於一個原始的待排序序列,往往可以通過分割的方法來歸結為多路合併排序。

基本思路

一個待排序的原始資料序列進行合併排序的基本思路是,首先將含有n個結點的待排序資料序列看作由n個長度為1的有序子表組成,將其依次兩兩合併,得到長度為2的若干有序子表;然後,再對這些子表進行兩兩合併,得到長度為4的若干有序子表……,重複上述過程,一直到最後的子表長度為n,從而完成排序過程。

演算法步驟

  1. 申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合併後的序列;
  2. 設定兩個指標,最初位置分別為兩個已經排序序列的起始位置;
  3. 比較兩個指標所指向的元素,選擇相對小的元素放入到合併空間,並移動指標到下一位置;
  4. 重複步驟 3 直到某一指標達到序列尾;
  5. 將另一序列剩下的所有元素直接複製到合併序列尾。

動圖演示

程式碼實現:java

public class ClassP4_7 {

    public static void main(String[] args) {
        int[] arr = sort(new int[]{5, 4, 3, 2, 1});
        System.out.println(ArrayUtils.toString(arr));
//{1,2,3,4,5} } public static int[] sort(int[] sourceArray) { // 對 arr 進行拷貝,不改變引數內容 int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); if (arr.length < 2) { return arr; } int middle = (int) Math.floor(arr.length / 2); int
[] left = Arrays.copyOfRange(arr, 0, middle); int[] right = Arrays.copyOfRange(arr, middle, arr.length); return merge(sort(left), sort(right)); } protected static int[] merge(int[] left, int[] right) { int[] result = new int[left.length + right.length]; int i = 0; while (left.length > 0 && right.length > 0) { if (left[0] <= right[0]) { result[i++] = left[0]; left = Arrays.copyOfRange(left, 1, left.length); } else { result[i++] = right[0]; right = Arrays.copyOfRange(right, 1, right.length); } } while (left.length > 0) { result[i++] = left[0]; left = Arrays.copyOfRange(left, 1, left.length); } while (right.length > 0) { result[i++] = right[0]; right = Arrays.copyOfRange(right, 1, right.length); } return result; } }

參考:

1.Java常用演算法手冊4.8

2.1.5 歸併排序(https://www.runoob.com/w3cnote/merge-sort.html)