【數據結構與算法】—— 歸併排序

歸併排序(MERGE-SORT)是創建在歸併操做上的一種有效的排序算法,該算法是採用分治法(Divide and Conquer)的一個很是典型的應用。將已有序的子序列合併,獲得徹底有序的序列;即先使每一個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱爲二路歸併。歸併排序是一種穩定的排序方法。
<!--more-->java

歸併介紹

前面有介紹,這裏依然不作介紹算法

歸併思想

核心思想:不斷的將大的數組分紅兩個小數組,直到不能拆分爲止,即造成了單個值。此時使用合併的排序思想對已經有序的數組進行合併,合併爲一個大的數據,不斷重複此過程,直到最終全部數據合併到一個數組爲止。數組

歸併分析

歸併排序

歸併排序流程

我在網上看到一大神寫的關於 歸併排序的圖解,很清楚明瞭。能夠借鑑一下: 【圖解】歸併排序ide

圖解歸併

圖解歸併-動態
圖解歸併-動態spa

代碼實現

Java程序是網上獲得哪位大神提供的。scala

public static void main(String[] args) {
        int[] data = {8, 4, 5, 7, 1, 3, 6, 2};
        mergeSort(data);
        System.out.println(Arrays.toString(data));
    }
    public static void mergeSort(int[] arr) {
        sort(arr, 0, arr.length - 1);
    }
    public static void sort(int[] arr, int L, int R) {
        if (L == R) {
            return;
        }
        int mid = L + ((R - L) >> 1);
        sort(arr, L, mid);
        sort(arr, mid + 1, R);
        merge(arr, L, mid, R);
    }
    public static void merge(int[] arr, int L, int mid, int R) {
        int[] temp = new int[R - L + 1];
        int i = 0;
        int p1 = L;
        int p2 = mid + 1;
        // 比較左右兩部分的元素,哪一個小,把那個元素填入temp中
        while (p1 <= mid && p2 <= R) {
            temp[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
        }
        // 上面的循環退出後,把剩餘的元素依次填入到temp中
        // 如下兩個while只有一個會執行
        while (p1 <= mid) {
            temp[i++] = arr[p1++];
        }
        while (p2 <= R) {
            temp[i++] = arr[p2++];
        }
        // 把最終的排序的結果複製給原數組
        for (i = 0; i < temp.length; i++) {
            arr[L + i] = temp[i];
        }
    }
def main(args: Array[String]): Unit = {
    var left: List[Int] = List(
      4, 5, 7, 8
    )
    var right: List[Int] = List(1, 2, 3, 6)
    val ints: List[Int] = merge(left, right)
    println(ints)
  }
  def merge(left: List[Int], right: List[Int]): List[Int] = (left, right) match {
    case (Nil, _) => right
    case (_, Nil) => left
    case (x :: xTail, y :: yTail) =>
      if (x <= y) x :: merge(xTail, right)
      else y :: merge(left, yTail)
  }

在歸併以前,首先先要對兩個數組作排序,要保證他們兩個有序,而後在進行歸併。以前的有序的過程可使用快速排序算法。code

在歸併中,通常會使用 快排 + 歸併 來完成一個數組的排序。blog

時間複雜度:O(nlogn)排序

空間複雜度:O(N),歸併排序須要一個與原數組相同長度的數組作輔助來排序rem

相關文章
相關標籤/搜索