算法-归并排序算法(六)

大家好啊,好久没写博客了,主要是前段时间比较忙,很抱歉很久都没更新了。是时候更新了~

上次讲了快排,这次讲一讲归并排序。首先在正片前多说两句,归并排序用的还是蛮多的,在JAVA API中,归并排序一度是默认的排序方式,当然实际上JAVA里是分了很多种情况考虑的,以Array的sort()为例,当数组长度小于某个值时,其实使用的是插入排序。其他的还有一些判断,在写完排序算法后,我会分析一下JAVA API的排序算法。

归并排序定义

相信学习算法的大家,对“分而治之”这一思想是有充分理解的,其实归并排序也是如此,也是先通过大化小,最后再把小的组合成大的,完成排序。示意图如下:

在这里插入图片描述
诸位看完,是不是已经有了算法实现的大概思路?哈哈,需要注意的是,每次要做合并(merge)的两个数组,都是排好序的,我们需要从左侧开始依次比较,填入新的数组中。

代码实现,写了好久,注意看注释~

//首先请先看merge那段代码,再回头看这一段
    public  void sort(int[] arr,int left,int right){
    //递归基:如果左右相等,则返回
        if (left==right) return ;
        //分割点为(left+right)/2
        //那么为何不直接这么写呢?因为int是有限的,相加可能越界,写成下面的写法会安全一些
        int division = left +(right-left)/2;
     //递归左边的
        sort(arr,left,division);
        //递归右边的
        sort(arr,division+1,right);
        //合并,merge!
        merge(arr,left,division+1,right);

    }
    
//虽然这一段在下面,但先来看这一段吧,这一段是合并的代码
    private void merge(int[] arr,int left,int right,int bound){
    //先解释一下入参,int[] arr,要合并的数组
    //                int left,左指针的位置,标志左数组的起点
    //                int right,左指针的位置,标志左数组的起点,同时也是左数组的边界
    //                int bound右边界的位置
        int[] tempArr = new int[bound-left+1];//我们需要一个临时数组来存放
        int index = 0;//记录临时数组插入位置的指针
        int mid = right-1;//左右数组的分割点
        int start =left;//记录左数组的起点
        //当左指针小于分割点,右指针小于边界时
        //此时说明我们还未比较完
        while (left<=mid && right<=bound){
        //当左数组当前值小于等于右数组当前值,我们把左数组的当前值加入临时数组
        //注意,这个等号是稳定性的关键!
            if (arr[left]<=arr[right])
                tempArr[index++] = arr[left++];
         //反之加入右数组的当前值
            else
                tempArr[index++] = arr[right++];
        }
        //左右数组往往是不等长的,当一个数组已经加完了之后,我们把另一个数组余下的数全部加入临时数组
        //再次强调,能这么做是因为左右数组是分别已经排好序了的
        while(left<=mid) tempArr[index++] = arr[left++];
        while (right<=bound) tempArr[index++] = arr[right++];
        //最后把临时数组的值给原数组
        for (int i = 0;i<tempArr.length;i++){
            arr[start++] = tempArr[i];
        }
    }

算法稳定性

归并排序是一种稳定的排序。

时间复杂度

对长度为n的文件,需进行 趟二路归并,每趟归并的时间为O(n),故其时间复杂度无论是在最好情况下还是在最坏情况下均是O(nlgn)。

空间复杂度

需要一个辅助向量来暂存两有序子文件归并的结果,故其辅助空间复杂度为O(n),显然它不是就地排序。
总而言之,
归并排序比较占用内存,但却是一种效率高且稳定的算法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值