歸併排序java實現

問題

使用歸併排序以下數組 [32, 12, 43, 5, 3, 8],使得排序後的結果爲:
[3, 5, 8, 12, 32, 43]

思路

解題須要如下兩個知識:java

一、歸併排序的核心思想是分治思想,就是把須要排序的規模分到最小,本題中是要分到什麼程度呢,也就是說分到每一個數組裏面只有一個元素,一個元素也就不用排了,就是這個元素自己數組

二、合併 兩個有序的數組合併成一個有序的數組,這也就是這個歸併排序名稱的由來,具體歸併的操做以下 兩個有序數組 a1=[1,3,5]和a2=[2,4,6] 合併以後是33=[1,2,3,4,5,6]。這裏面主要用到兩個指針,一個指向A1的開頭p1,一個指向A2的開頭p2,和一個空數組A3。而後比較a1[p1]和a2[p2]的大小,把小的放入到a3中,而後小的指針繼續往下走,直到其中的一個數組的元素都走完,而後把另一個數組的元素剩餘的部分所有放入到a3結尾處。圖例以下: 函數

編碼

/**
   * 歸併排序
   * @param a 待排序的數組
   */
  public void mergeSort(int[] a) {
    int[] temp = new int[a.length];
    mergeSortSub(a, temp, 0, a.length - 1);
  }

  /**
   * 須要用分治的代碼,其中left<right是跳出循環的條件。
   * 分治以後調用merge函數對數組進行合併
   * @param a 待排序的數組
   * @param temp 臨時用來存放數組的數組
   * @param left 分治之後的數組的左邊界
   * @param right 分治以後數組的右邊界
   */
  public void mergeSortSub(int[] a, int[] temp, int left, int right) {
    if (left < right) {
      int center = (left + right) / 2;
      mergeSortSub(a, temp, left, center);
      mergeSortSub(a, temp, center + 1, right);
      merge(a, temp, left, center + 1, right);
    }
  }


  /**
   * 一個數組從中間分爲兩個有序數組,合併這兩個有序數組
   *
   * @param a        待排序和合並的數組
   * @param temp     合併和排序的結果
   * @param leftPos  左邊有序數組起點
   * @param rightPos 右邊有序數組的起點
   * @param rightEnd 右邊的終點
   */
  public void merge(int[] a, int[] temp, int leftPos, int rightPos, int rightEnd) {

    int leftEnd = rightPos - 1;
    int tempPos = leftPos;
    int numElements = rightEnd - leftPos + 1;

    while (leftPos <= leftEnd && rightPos <= rightEnd) {
      int leftValue = a[leftPos];
      int rightValue = a[rightPos];
      if (leftValue > rightValue) {
        temp[tempPos] = rightValue;
        rightPos++;
      } else {
        temp[tempPos] = leftValue;
        leftPos++;
      }
      tempPos++;
    }
    while (leftPos <= leftEnd) {
      temp[tempPos] = a[leftPos];
      leftPos++;
      tempPos++;
    }
    while (rightPos <= rightEnd) {
      temp[tempPos] = a[rightPos];
      rightPos++;
      tempPos++;
    }
    for (int i = 0; i < numElements; i++, rightEnd--) {
      a[rightEnd] = temp[rightEnd];
    }
  }
//測試代碼
 @Test
  public void test_mergeSort() {
  	int[] array = new int[]{32, 12, 43, 5, 3, 8};
    int[] after = new int[]{3, 5, 8, 12, 32, 43};
    mergeSort(array);
    Assert.assertArrayEquals(after, array);
  }

其中代碼的執行流程以下圖: 測試

時間複雜度

O(NlogN)編碼

以上就是java實現歸併排序的全過程。最後再強調一遍,歸併排序的兩個關鍵點 分治合併有序數組指針

相關文章
相關標籤/搜索