归并排序专题-递归排序实现和普通方式实现(java)

归并排序是一种基于分治策略的排序算法,其时间复杂度为O(nlogn)。文章详细介绍了归并排序的基本步骤,包括如何将序列不断分割、对子序列排序以及合并有序序列,并提供了递归和非递归两种Java实现方法。

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

什么是递归排序

归并排序(Merge Sort)是一种基于分治思想的排序算法,它的基本思想是将待排序的序列不断地分割成两个子序列,直到每个子序列只有一个元素,然后再将这两个子序列合并成一个有序的序列。

归并排序的基本步骤如下:

将待排序的序列不断地分割成两个子序列,直到每个子序列只有一个元素。
对每个子序列进行排序,可以使用任何一种排序算法,例如插入排序、选择排序、快速排序等。
将排好序的子序列合并成一个有序的序列。

归并排序的时间复杂度为 O(nlogn),其中 n 是待排序序列的长度。

递归方式实现归并排序

  public static void mergeSort(int[] arr){
        if (arr == null || arr.length < 2){
            return;
        }
        process(arr,0,arr.length-1);
    }

递归写法:

 public static void process(int[]arr,int l,int r){
        if (l == r){ //base case 
            return;
        }
        int mid = l + ((r - l >> 1));
        process(arr,l,mid);
        process(arr,mid+1,r);
        merge(arr,l,mid,r);
    }

对分好的子数组进行合并

 public static void merge(int[]arr,int l,int mid,int r){
        int p1 = l; //左边数组的起始位置
        int p2 = mid + 1; //右边数组的起始位置
        int[]help = new int[r - l + 1]; //辅助数组长度等于左右数组之和
        int index = 0;
        while (p1 <= mid && p2 <= r){
        		//左右两边进行比较,小的先进辅助数组,指针移到下一位。
            help[index++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
        }
       //两个指针会有一个先越界,剩下的继续进辅助数组下面两个循环,只会进一个
        while (p1 <= mid){
            help[index++] = arr[p1++];
        }
        while (p2 <= r){
            help[index++] = arr[p2++];
        }
        //辅助数组排好序后,写进原数组。
        for (int i = 0; i < help.length;i++){
            arr[l+i] = help[i];
        }
    }

普通的方式实现递归排序

实现思想是,先定好步长,就是分治时,每次要分治的大小,我们开始步长定为1,然后每次步长进行乘以2.

  public static void mergeSort2(int[]arr){
        if (null == arr || arr.length < 2){
            return ;
        }
        //每次分治的大小,第一次设为1
        int mergeSize = 1;
        int N = arr.length;
        while (mergeSize < N ){
            int L = 0;
            while(L < N ){
            		//这个判断是,当步长大于N - L 时,说明现在只有左边数组有数据,右边数组没数据,这时不进行计算,留到下一次
                if (mergeSize >= N - L){
                    break;
                }
                int M = L + mergeSize - 1;
                //右边取值时,要注意边界,有可能mergesize 大于剩下的数量了,因此要取其中最小的值
                int R = M + Math.min(mergeSize,N - M - 1);
                //这个merge的方法和上面递归的merge的方法是同一个。
                merge(arr,L,M,R);
                //进行下一个循环
                L = R + 1;
            }
            //这个是为了防止溢出,megsize * 2 后可能会超过int最大值
            if (mergeSize > N/2){
                break;
            }
            //乘以2
            mergeSize <<= 1;

        }
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值