归并排序简析

参考连接:
https://blog.csdn.net/morewindows/article/details/6678165/
SteveWang
www.cnblogs.com/eniac12/p/5329396.html

1.递归的归并排序的思路

归并排序是由若干次组内元素的归并排序一起完成的.
首先,对两个已经有序的数组进行合并的操作比较简单,代码如下

    public static long[] mergeSortArr(long arrA[], long arrB[]) {
        int countA = arrA.length;
        int countB = arrB.length;
        long arrMerge[] = new long[countA + countB];
        int indexA = 0, indexB = 0, indexMerge = 0;
        while (indexA < countA && indexB < countB) {
            if (arrA[indexA] < arrB[indexB]) {
                arrMerge[indexMerge++] = arrA[indexA++];
                // indexA++;
            } else {
                arrMerge[indexMerge++] = arrB[indexB++];
                // indexB++;
            }
            // indexMerge++;
        }
        while (indexA < countA) {
            arrMerge[indexMerge++] = arrA[indexA++];
        }
        while (indexB < countB) {
            arrMerge[indexMerge++] = arrB[indexB++];
        }
        return arrMerge;
    }

这个操作可以理解为一次归并排序,但是对于任意数组,数据可能不是有序的,那么如何进行有序数组的归并呢? 既然数组内数据不是有序的,那么我们就把数组分割,一分为二,再一分为二……直到分割成每个组内只有一个数据,每个数据可以理解为一个个长度为1的有序数组,然后对长度为1的数组进行归并排序,归并之后,数组内会存在长度更大的有序数组,再对这些有序数据进行归并,一点点叠加,直到归并结束.
归并排序的动图

2.递归的归并排序的实现

public class MergeSort {

    // 合并有序数组
    public static void mergeSortArr(long arr[], int start, int mid, int end,
            long arrMerge[]) {
        int s1 = start;// start 1
        int s2 = mid + 1;// start 2
        int limit1 = mid;
        int limit2 = end;
        int mergeIndex = 0;
        while (s1 <= limit1 && s2 <= limit2) {
            if (arr[s1] < arr[s2]) {
                arrMerge[mergeIndex++] = arr[s1++];
            } else {
                arrMerge[mergeIndex++] = arr[s2++];
            }
        }
        while (s1 <= limit1) {
            arrMerge[mergeIndex++] = arr[s1++];
        }
        while (s2 <= limit2) {
            arrMerge[mergeIndex++] = arr[s2++];
        }
        // 将排好序的数据存到arrMerge中
        for (int i = 0; i < mergeIndex; i++) {
            arr[start + i] = arrMerge[i];
        }

    }

    // 归并排序递归思路
    public static void mergeSort(long arr[], int start, int end,
            long arrMerge[]) {
        if (start < end) {// 递归的结束条件:数组被分割成一个个数据(如果只有一个数据,那么start==end)
            int mid = (start + end) / 2;
            mergeSort(arr, start, mid, arrMerge);// 对左半侧实施归并
            mergeSort(arr, mid + 1, end, arrMerge);// 对右半侧实施归并
            mergeSortArr(arr, start, mid, end, arrMerge);
        }
    }

    public static void main(String[] args) {
        long a[] = { 1, 2, 3, 4, 5, 77, 3, 4, 66, 2, 11, 4, 5 };
        long mer[] = new long[a.length];
        mergeSort(a, 0, a.length - 1, mer);

        if (mer != null) {
            for (int i = 0; i < mer.length; i++) {
                System.out.println(mer[i]);
            }
        }
    }

}

3.递归的归并排序的效率

递归排序分为两个部分:
1.将数据分割为一个个长度为一的数据
2.对这些数据进行归并
将数据分割为一个个长度为一的数据的时间复杂读为O(logN)(对长度为n的数组拆分,第一次均分为2份,第二次4份,第三次8份……最终每份只有一个元素需要拆分 log2n l o g 2 n 次)对有序数据进行归并排序,与归并的两个数组的长度成正比,因此时间复杂度为O(N),那么归并排序的时间复杂度就是O(NlogN)了

4.题外(教训):debug的重要性

自己在编写归并排序的mergeSortArr方法时,一直报错数组越界,从头看到尾,仔仔细细看了n遍,都没有发现错误.最后实在没办法,用System.out.println()+debug找到问题出现在边界值上,(即<是否加=的情况).我们在写代码时,往往会觉得自己的代码逻辑没有问题,千看万看就是找不到问题点,因为我们往往会顺着我们的思路读代码,但是程序的执行往往并不是按照我们心中所想的步骤进行的,这时就需要多多debug了.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值