归并排序实现

本文深入讲解归并排序算法,采用分而治之策略,通过递归将数组分割为子问题,然后合并已排序的子数组,实现高效排序。提供详细的代码实现及运行结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

归并排序

归并排序就是利用分而治之的思想,将大规模的问题分解成若干小规模的子问题,当分到规模大小为1的时候,子问题是有序的,这个时候归并已经排好序的子问题,不断归并,直至整个大规模的问题都已经排好序。

举个例子

有一个数组: 3 2 6 8 1

第一次切分: 3 2 6 8 1

第二次切分: 3 2 6 8 1

第三次切分: 3 2 6 8 1

第一次归并: 3 2 6 1 8

第二次归并: 2 3 1 6 8

第三次归并: 1 2 3 6 8

代码实现

public class MergeSort {
    /**
     * 归并排序:利用了分治思想,将大规模问题分解为一个个小规模的问题,小规模与大规模的解法相似
     * 利用递归可以很好的解决分治问题,以下用二路归并解决问题
     */
    public static void mergeSort(int[] arr, int start, int end) {
        //递归的关键在于处理好边界问题,当要处理的子问题规模小于等于1的时候,子问题就已经解决了
        if (end - start > 0) {
            //否则将问题一分为二,递归执行子问题
            int middle = (start + end) / 2;
            mergeSort(arr, start, middle);
            mergeSort(arr, middle + 1, end);
            //子问题执行完毕需要进行归并
            merge(arr, start, end, middle);
        }
    }

    //合并两个子结果
    private static void merge(int[] arr, int start, int end, int middle) {
        int mergeLen = end - start + 1;
        int[] merged = new int[mergeLen];
        //arr的start到middle和middle+1到end都是有序的
        int i = start, j = middle + 1, k = 0;
        //先取两部分的公共部分
        while (i <= middle && j <= end) {
            if (arr[i] > arr[j]) {
                merged[k++] = arr[j++];
            } else {
                merged[k++] = arr[i++];
            }
        }
        //针对过长的一部分做处理
        while (i <= middle) {
            merged[k++] = arr[i++];
        }
        while (j <= end) {
            merged[k++] = arr[j++];
        }
        //修改的部分复制回原数组
        System.arraycopy(merged, 0, arr, start, mergeLen);
    }

    public static void main(String[] args) {
        Random r = new Random();
        int[] arr = new int[20];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = r.nextInt(100);
        }
        //未排序
        System.out.printf("排序前:%s \n", Arrays.stream(arr).boxed().map(Object::toString).collect(Collectors.joining(" ")));
        //排好序
        mergeSort(arr, 0, arr.length - 1);
        System.out.printf("排序后:%s \n", Arrays.stream(arr).boxed().map(Object::toString).collect(Collectors.joining(" ")));
    }
}

运行结果

排序前:60 50 68 74 63 88 38 68 92 81 27 11 52 65 10 91 21 45 84 81 
排序后:10 11 21 27 38 45 50 52 60 63 65 68 68 74 81 81 84 88 91 92
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值