归并排序实现(Java)

归并排序法(Merge Sort,以下简称MS)是分治法思想运用的一个典范。其主要算法操作可以分为以下步骤:
Step 1:将n个元素分成两个含n/2元素的子序列
Step 2:用MS将两个子序列递归排序(最后可以将整个原序列分解成n个子序列)
Step 3:合并两个已排序好的序列
易知,MS的关键在于Merge过程。对于这一过程的理解,算法导论中给出了一个形象的模型。
即假设桌面上有两堆已排序好的的牌,且每一堆都正面朝下放置。然后我们分别从两堆牌中选取顶上的一张牌(选取之后,堆顶端又会露出新的顶牌),选取较小的一张,放入输出堆,另一张放回。
重复这一步骤,最后直到一堆牌为空。由于两堆牌都是已排序,所以可知,只要将剩下的那堆牌盖到输出堆即完成整个排序过程。

    public int[] mergeSort(int[] A, int n) {
        // write code here
        sort(A, 0, n - 1);
        return A;
    }

    public void sort(int[] data, int left, int right) {
        if (left < right) {
            int middle = (left + right) / 2;
            // 划分左右
            sort(data, left, middle);
            sort(data, middle + 1, right);
            // 合并左右
            merge(data, left, middle, right);
        }
    }

    // 合并左右两个子数组
    public void merge(int[] data, int left, int middle, int right) {
        // 临时数组
        int[] tempArr = new int[right - left + 1];
        // 左边数组游标
        int leftIndex = left;
        // 右边数据游标
        int rightIndex = middle + 1;
        // 临时数组游标
        int tempIndex = 0;

        while (leftIndex <= middle && rightIndex <= right) {
            // 临时数组选取左、右子数组中小数值
            if (data[leftIndex] < data[rightIndex]) {
                tempArr[tempIndex++] = data[leftIndex++];
            } else {
                tempArr[tempIndex++] = data[rightIndex++];
            }
        }
        // 剩余的直接放入
        while (leftIndex <= middle) {
            tempArr[tempIndex++] = data[leftIndex++];
        }
        // 剩余的直接放入
        while (rightIndex <= right) {
            tempArr[tempIndex++] = data[rightIndex++];
        }
        // 将临时数组放回原数组相应位置
        int temp = 0;
        while ((temp + left) <= right) {
            data[left + temp] = tempArr[temp];
            temp++;
        }
    }

归并排序的效率是比较高的,设数列长为N,将数列分开成小数列一共要logN步,每步都是一个合并有序数列的过程,时间复杂度可以记为O(N),故一共为O(N*logN)。因为归并排序每次都是在相邻的数据中进行操作,所以归并排序在O(N*logN)的几种排序方法(快速排序,归并排序,希尔排序,堆排序)也是效率比较高的

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值