java排序算法之 --- 归并排序

  说归并排序之前先说明一下分治的思想。何为分治?分治的思想就是将一个规模为 N 的问题分解为 K 个规模较小的子问题,这些子问题相互独立且与原问题性质相同,只要求出了这些子问题的解,就可得到原问题的解。

  归并排序就是采用了这样的思想,本次要实现的是二路归并排序,就是将一组待排序的数组分成两个两个子数组,子数组又继续分为子子数组,直到每个数组中只有一个元素,然后每次将两个子数组合并成一个有序数组,直至所有子数组合并结束。

  举个简单的小例子:

    int arr[] = {4,1,3,2}

    递归分成子数组:       {4,1,3,2}  -->  {4,1} {3,2} -->  {4} {1} {3,2}

    第一轮合并成有序数组:    {1,4} {2,3}

    第二轮合并成有序数组:    {1,2,3,4}

 

 

  核心代码如下:

  /**
     * 
     * @param arr    要排序的数组
     * @param left    数组的开始位置
     * @param right    数组的结束位置
     */
    public static void mergesort(int[] arr,int left,int right) {
        if(left < right) {                    //保证数组的开始位置始终小于结束位置
            int mid = (left + right) / 2;    //寻找分治的中间位置
            mergesort(arr,left,mid);        //数组左边部分进行递归排序
            mergesort(arr,mid+1,right);        //数组右边部分进行递归排序
            merge(arr,left,mid,right);        //不可再分的时候进行数组的合并并排序
        }
    }
    
    /**
     * 合并两个数组,并从小到大排序
     * 
     * @param arr    要排序的数组
     * @param left    数组的开始位置
     * @param mid    数组的中间位置
     * @param right    数组的结束位置
     */
    public static void merge(int[] arr,int left, int mid, int right) {
        int i = left;        //第一个数组的起始位置
        int j = mid + 1;    //第二个数组的起始位置
        int k = left;        //合并后的数组的起始位置
        int[] temp = new int[arr.length];    //存储合并后的数组
        while(i <= mid && j <= right) {        //判断两数组下标是否越界,其中一个数组遍历完则结束循环
            if(arr[i] <= arr[j]) {            //判断两数组下标对应的元素大小并存入临时数组
                temp[k++] = arr[i++];
            }else {
                temp[k++] = arr[j++];
            }
        }
        while(i <= mid) {                    //如果第一个数组未全部存入临时数组则存入
            temp[k++] = arr[i++];
        }
        while(j <= right) {                    //如果第二个数组未全部存入临时数组则存入
            temp[k++] = arr[j++];
        }
        for(i = left; i <= right; i++) {    //把临时数组中的元素存入原数组中
            arr[i] = temp[i];
        }
    }

  归并排序算法是一种稳定算法,时间复杂度为O(n log n),空间复杂度为O(n)

转载于:https://www.cnblogs.com/zincpool/p/7545966.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值