[JDK17]归并排序的实现原理与代码实现(详细图解以及代码执行过程)

归并排序执行流程原理(图解):

JDK17代码实现:

package SortAlgorithm.MergerSort;

import java.util.Arrays;

public class MergerSort {

    public static void main(String[] args) {
        int[] arr = {456,10,78,3,19,28,54,321,-84,97};
        int[] temp = new int[arr.length];
        System.out.println("原数组: "+ Arrays.toString(arr));

        MergerSort.mergerSort(arr,0,arr.length-1,temp);
        
        System.out.println("排序后: "+ Arrays.toString(arr));

    }

    /**
     * 归并排序
     * @param arr 待排序数组
     * @param left 合并时左子项的左边界
     * @param right 合并时右子项的右边界(调用时应该传arr.length-1)
     */
    public static void mergerSort(int[] arr,int left,int right,int[] temp){
        //传入一个数组,先计算中间索引,用于分解数组(mid在回溯期间也是左子项的右边界)
        int mid = (left+right) / 2;

        //如果l==r 说明此时数组已经分解剩一个元素,只剩一个元素没必要比较,直接return返回到上一层栈帧
        if (left == right) return;

        //向左遍历,分解左边的数组
        mergerSort(arr,left,mid,temp);

        //向右遍历,分解右边的数组
        mergerSort(arr,mid + 1,right,temp);

        //能执行到下面的语句,说明已经开始回溯(即已经分解到只剩一个元素)
        //下面开始合并操作

        //l1,l2用来后续合并操作时遍历左右子项
        //l1是左子项的左边界,l2是右子项的左边界
        int l1 = left;
        int l2 = mid + 1;

        //创建一个指向temp数组的索引t,便于操作temp数组
        int t = l1;
        //l1和l2索引在边界内才允许遍历左右子项
        while (l1 <= mid && l2 <= right) {
            if (arr[l1] <= arr[l2]) {
                temp[t] = arr[l1];
                //左子项索引和temp索引同步后移
                l1++;
                t++;
            }else {
                temp[t] = arr[l2];
                //右子项索引和temp索引同步后移
                l2++;
                t++;
            }
        }
        //退出循环,说明l1或者l2索引其中一个出现越过边界的情况
        //把没有越过边界的一边剩下的数据照搬到temp数组中
        //li <= mid 说明是左子项的索引没越界,把左子项剩余的数据追加到temp
        while (l1 <= mid) {
            temp[t] = arr[l1];
            l1++;
            t++;
        }
        //l2 <= right 说明是右子项的索引没越界,把右子项剩余的数据追加到temp
        while (l2 <= right) {
            temp[t] = arr[l2];
            l2++;
            t++;
        }

        //上述操作完成后,temp数组内就有了这轮排序完成后的数据
        //将这一轮排好序的temp数组赋值到原数组中,修改原数组数据
        //将t复位,同步遍历temp数组和原数组,然后覆盖原数组对应索引的数据
        t = left;
        while (t <= right) {
            //t既是原数组的索引,也是temp数组的索引,因为当初存到temp数组时就是对应着arr数组的索引存的
            arr[t] = temp[t];
            t++;
        }
        //修改原数组完成,该层栈帧结束,自动回溯到上一层栈帧

    }
}

测试图:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值