合并排序是一种通过分治模式解决排序问题的算法,这种排序算法根据具体细节的不同可以有很多实现。他拥有O(N logN)的最差运行时间,而且是一个很好的递归实例。
实现合并排序最重要的是递归的base case和边界条件的处理,如下是对整型数组的合并排序Java实现。
- public static void mergesort(int[] array, int[] temp, int start, int end) {
- if (start == end) return;
- int center = (start + end)/2;
- mergesort(array, temp, start, center);
- mergesort(array, temp, center+1, end);
- int left = start;
- int right = center + 1;
- int current = left;
- while(left<=center&&right<=end) {
- if (array[left]<=array[right]) {
- temp[current++] = array[left++];
- } else {
- temp[current++] = array[right++];
- }
- }
- while(left<=center) {
- temp[current++] = array[left++];
- }
- while(right<=end) {
- temp[current++] = array[right++];
- }
- for (int i = start; i <= end; i++) {
- array[i] = temp[i];
- }
- }
请注意以上代码中temp的运用,它被声明为一个和待排序数组相同大小的数组,并被传入方法中。我们可以使用它的任意部分作为中间结果的存储,这样就免于每次调用声明一个local数组,从而达到内存的高效使用。当然,这还不是最有效的解决方法,我们甚至可以使用更少的内存,但是算法的实现将变得相当复杂。
以上的实现将所有的代码包含在一个方法中,显然不是良好的程序设计风格,我们可以做如下改进。
- public static void mergesort(int[] array, int[] temp, int start, int end) {
- if (start == end) return;
- int center = (start + end)/2;
- mergesort(array, temp, start, center);
- mergesort(array, temp, center+1, end);
- merge(array, temp, start, center+1, end);
- }
- public static void merge(int[] array, int[] temp, int left, int right, int end) {
- int start = left;
- int center = right - 1;
- int current = left;
- while(left<=center&&right<=end) {
- if (array[left]<=array[right]) {
- temp[current++] = array[left++];
- } else {
- temp[current++] = array[right++];
- }
- }
- while(left<=center) {
- temp[current++] = array[left++];
- }
- while(right<=end) {
- temp[current++] = array[right++];
- }
- for (int i = start; i <= end; i++) {
- array[i] = temp[i];
- }
- }
如此代码中divide和merge的部分就分离在两个方法中,通过传递参数达到和第一段代码相同的排序作用。