3.5 归并排序的java实现

归并排序

1.基础理论

1.1 基本描述

归并排序以最坏时间复杂度O(N log N)运行,它所使用到的比较次数几乎是最优的,它是递归算法的一个很好的实例。

这个排序算法中基本的操作就是合并两个已经排序的表。

因为输入的两个表是已排序的,所以若将输出放到第三个表中, 则该算法可以通过对输入数据一趟排序来完成。

合并算法图示如下:


在这里插入图片描述

所以归并排序算法的步骤描述为:

如果N=1,那么只有一个元素直接返回结果,否则递归的将前本部分数据和后半部分数据各自归并排序,

得到排序后的两部分数据,然后使用上面描述的合并算法再将这两部分合并到一起。

也就是说最小子问题就是N=2

例如:

我们想将这个数组{24,13,26,1,2,27,38,15}排序,

我们递归的将前四个数据和后四个数据分别排序,得到
{24},{13},{26},{1},{2},{27},{38},{15},

然后使用归并方法对{24} {13} 进行归并得到{13,24}

对{26} {1} 进行归并得到{1,26}

对{2},{27} 进行归并得到{2,27}

对{38},{15} 进行归并得到{15,38}

接着对 {13,24} ,{1,26}进行归并得到{1,13,24,26}

对{2,27},{15,38}进行归并得到{2,15,27,38}

最后 我们将{1,13,24,26},{2,15,27,38}这两部分进行合并,最后得到{1,2,13,15,24,26,27,38}

该算法使用了经典的分治策略, 它将问题分成一些小的问题然后递归求解。

2. Java代码实现

class Test{
    /**
     * 合并两个已经排好序的数组
     * @param a
     * @param left
     * @param mid
     * @param right
     */
    public static void merge(int[] a, int left,int mid,int right) {

        int[] result = new int[right-left+1];

        // p1,p2是检测指针, index是存放指针
        int p1 = left, p2 = mid+1, index = 0;
        // 执行双数组元素比较
        while (p1<=mid&&p2<=right) {
            if(a[p1]<=a[p2]){
                result[index++] = a[p1++];
            }
            else{
                result[index++] = a[p2++];
            }
        }

        while (p1<=mid) result[index++] = a[p1++];
        while (p2<=right) result[index++] = a[p2++];

        System.arraycopy(result, 0, a, left, result.length);

    }

    /**
     * 归并排序,采用分治,递归思想
     * @param a
     * @param start
     * @param end
     */
    public static void mergeSort(int[] a,int start,int end) {
        if(start < end){
            int mid = (start+end)/2;
            mergeSort(a,start,mid);
            mergeSort(a,mid+1,end);
            merge(a,start,mid,end);
        }
    }

    public static void mergeSortTest() {
        int[] numbs = {24,13,26,1,2,27,38,15};
        mergeSort(numbs,0,numbs.length-1);
        System.out.println(Arrays.toString(numbs));
    }

    public static void main(String[] args) {
        mergeSortTest();
    }
}

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小牧之

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值