排序 - 归并排序 [2]

来源:互联网 发布:thinkpad摄像头软件 编辑:程序博客网 时间:2024/05/16 23:55


我们知道归并排序是拆分和合并两部分。

说完了归并排序的 拆分部分

继续说说合并部分。

 

还是先回顾下拆分吧。

随便说个数组 { 9, 2, 7, 1, 3, 6, 5, 4}

拆分过程:
   9,  2, 7, 1          3, 6, 5,4

 9, 2      7,1       3, 6     5, 4          

9  2     7   1       3   6     5   4 

 

好,到此我们对原数组完成了拆分,如果你不了解拆分,请一定看我的上一篇来弄懂拆分是如何工作的。

 

上面的拆分结果是最终的结果,其实合并是穿插在拆分过程中的。

 

当 9,2,7,1  --> 9,2 --> 9 & 2 的时候,9是某次递归中的左半部分,而2是这次递归中的右半部分。

当左半部分和右半部分都完成拆分的时候,我们就需要对他进行合并。

 

合并规则:

1. 创建一个数组,数组长度等于待合并左半部分和右半部分的数组元素总和;

2. 比较左面数组和右面数组中的第一个元素,选其较小者放入数组的第一个元素位置;

    2.5. 如果左面数组和右面数组都只有一个元素,那么此时我们已经处理了其中一个,对上例来讲,我们已经把 右面数组的唯一元素:2 放入了数组中,那么就只剩下左面元素:9;再将9直接追加到新数组的后面即可;

3. 综合2和2.5,我们知道合并是这样进行的:总是选择两边较小的元素追加到新元素的下一个元素的位置;

4. 当其中一部分(左面部分或右面部分)处理完成后,将另一部分的所有元素直接追加到新数组的后面,如此完成合并。

 

合并过程如下:

9  2    7   1     3  6     5  4

2,9     1,7        3,6      4,5

1,2,7,9            3,4,5,6

1,2,3,4,5,6,7,9

 

我在上一篇中提到一个问题:

拆分的结果就是每个元素都被拆分为一个单元,那干脆直接将每个元素都当做一个单元来处理不就得了,干嘛还做什么拆分?

原因在合并过程中就体现出来了。

 

1. 细心点,你会发现每次合并的左右两半部分数组都是 有序 的,只有有序,才能用上面的合并的规则;

2. 拆分和合并是一个递归过程,递归,还是递归,还要花些时间理解。

 

这篇写的不好。心不在焉。。如果你看到觉得不明白,欢迎讨论。

package r; public class MyMergeSort {  public static int[] array = {19, 1,90, 22, 11, 12, 9, 3};  public static void mergeSort(int[] sortArr, int start, int end) {    int len = end - start;    if (len < 1) return;    else {      int mid = start + len / 2;      printArr(sortArr, start, mid);      printArr(sortArr, mid + 1, end);          System.out.println("======================");      mergeSort(sortArr, start, mid);      mergeSort(sortArr, mid + 1, end);           merge(sortArr, start, mid, mid+1, end);           System.out.println("*************PRINT *********");      printArr(sortArr, start, end);    } }  private static void merge(int[] sortArr, int leftStart, int leftEnd, intrightStart, int rightEnd) {    int leftPointer = leftStart;    int rightPointer = rightStart;       int[] sortedArr = new int[rightEnd -leftStart + 1];    int index = -1;    while (leftPointer <= leftEnd &&rightPointer <= rightEnd) {      index++;      int s = getSmaller(sortArr, leftPointer,rightPointer);      sortedArr[index] = sortArr[s];           if (s == leftPointer) leftPointer++;      else rightPointer++;    }       if (leftPointer <= leftEnd) {      for (int i = leftPointer; i <=leftEnd; i++) {        sortedArr[++index] = sortArr[i];      }    }       if (rightPointer <= rightEnd) {      for (int i = rightPointer; i <=rightEnd; i++) {        sortedArr[++index] = sortArr[i];      }   }       // Copy back    for (int i = 0; i < sortedArr.length;i++) {      sortArr[leftStart + i] = sortedArr[i];    } }  private static int getSmaller(int[] sortArr, int leftPointer, intrightPointer) {    if (sortArr[leftPointer] <sortArr[rightPointer])      return leftPointer;    else      return rightPointer; }  private  static voidprintArr(int[] arr, int start, int end) {    for (int i = start; i <= end; i++) {      System.out.print(arr[i] + "  ");    }    System.out.println("\r\n--------"); }   public static void main(String[] args) {    mergeSort(array, 0, array.length - 1);   //    printArr(array, 0, array.length - 1); }}


 

 

 

原创粉丝点击