算法-归并排序

1.归并排序

前面我们介绍了快速排序和希尔排序,快速通过寻找基准数的方式将小于基准数放到基准数左边大于基准数的值放到右边,再递归排序。 希尔排序则是对数列进行分段,然后使用插入排序重新排序。是两种不同的思路 ,归档排序则是第三种不同的排序思路

  • 平均时间复杂度O(nlogn)
  • 最坏时间复杂度O(nlogn)
  • 最好时间复杂度O(nlogn)
  • 空间复杂度O(n)
  • 是否稳定 稳定

二.思路

归并排序有几个关键点
1.low 排序数组的起点
2.height 排序数组的终点
3.mid 排序数组的中间点 也叫切割点
4.递归结束条件 low>=height 其实就是low==height

总思路是对数组进行无线对等切割,然后合并的时候排序,也叫分治法
这里需要注意的几个点

  • 要合并的两个数组一定的排序好的数组
  • 合并后的数组一定是排序好的
    因此我们可以使用双指针的方法对两个数组进行排序
    具体是开辟另一个数据空间,把两个数组的值从小到大放到数组里,当一个数组遍历完后,另一个数组的值一定是比临时数组,并且是有序的,因此直接放到临时数组后即可,观察到这一点有助于我们理解并且书写算法

在这里插入图片描述

三.实现

 /**
     * 归并排序  思路  拆分 归并的同时排序
     * @param array
     * @return
     */
    public static int[] split(int[] array,int low,int height){
        if(low>=height){
            return array;
        }
        int mid = (low+height)/2;
        //拆分
        split(array,low,mid);
        split(array,mid+1,height);

        //合并
        return merge(array,low,height,mid);
    }

    public static int[] merge(int[] array,int low,int height,int mid){

        //通过双指针排序
        int left = low;
        int right = mid+1;

        //开辟临时数组空间
        int[] temp = new int[height-low+1];
        int tempIndex = 0;

        //双指针对low->mid mid+1->height 两个数组进行排序 当一边遍历完 另一边没遍历的值一定比已经遍历的大
        while(left<=mid && right<=height){
           if(array[left]<array[height]){
               temp[tempIndex++] = array[left++];
           }else {
               temp[tempIndex++] = array[right++];
           }
        }

        //处理low->mid未遍历完的数据
        while (left<=mid){
            temp[tempIndex++] = array[left++];
        }

        while (right<=height){
            temp[tempIndex++] = array[right++];
        }
        tempIndex--;
        //将临时排序好的数组放到正式的数组中去 注意复制需要从下标low开始
        while (tempIndex>=0){
            array[low+tempIndex] = temp[tempIndex];
            tempIndex--;
        }
        return array;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值