A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

今天我们来聊一聊归并排序.归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(n log n)的时间复杂度。但是有利就有弊,归并排序需要额外的内存空间。
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。归并排序是一种稳定的排序方法。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。
归并排序的实现原理:
  • 把长度为n的输入序列分成两个长度为n/2的子序列;
  • 对这两个子序列分别采用归并排序;
  • 将两个排序好的子序列合并成一个最终的排序序列。

我们下面用一个动图来演示一下:

通过这两个动图,相信大家就能很好的理解归并排序的原理.下面重点来了. 我们用java代码实现一下.
[AppleScript] 纯文本查看 复制代码
/**
    * 归并排序
    *
    * @param array
    * @return
    */
   public static int[] MergeSort(int[] array) {
       if (array.length < 2) return array;
       int mid = array.length / 2;
       int[] left = Arrays.copyOfRange(array, 0, mid);
       int[] right = Arrays.copyOfRange(array, mid, array.length);
       return merge(MergeSort(left), MergeSort(right));
   }
   /**
    * 归并排序——将两段排序好的数组结合成一个排序数组
    *
    * @param left
    * @param right
    * @return
    */
   public static int[] merge(int[] left, int[] right) {
       int[] result = new int[left.length + right.length];
       for (int index = 0, i = 0, j = 0; index < result.length; index++) {
           if (i >= left.length)
               result[index] = right[j++];
           else if (j >= right.length)
               result[index] = left[i++];
           else if (left[i] > right[j])
               result[index] = right[j++];
           else
               result[index] = left[i++];
       }
       return result;
   }


最后我们来分析一下归并算法的时间复杂度:
最佳情况:T(n) = O(n)  最差情况:T(n) = O(nlogn)  平均情况:T(n) = O(nlogn)
好了我们归并算法就讲到这里.希望大家了解算法能有所裨益.




0 个回复

您需要登录后才可以回帖 登录 | 加入黑马