归并排序

归并排序基本思想

归并排序是每次选取当前序列的中点,分为两部分,继续递归下去,直到左右两部分已经有序,然后合并的话,利用一个数组从小到大存下来左右两部分的值,然后从左端点到右端点依次赋值即可,存两部分的值其实是用到了双指针的思想


代码

#include<stdio.h>
const int N=1e5+50;
int a[N],temp[N];
void merge_sort(int l,int r){
    if(l>=r) return ;
    int mid=l+r>>1;
    merge_sort(l,mid);
    merge_sort(mid+1,r);
    int i=l,j=mid+1,cnt=0;
    while(i<=mid && j<=r){
        if(a[i]<=a[j]) temp[++cnt]=a[i++];
        else temp[++cnt]=a[j++];
    }
    while(i<=mid) temp[++cnt]=a[i++];
    while(j<=r) temp[++cnt]=a[j++];
    for(i=l,j=0;i<=r;i++) a[i]=temp[++j];
}
int main(){
    int n;
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;i++) {
            scanf("%d",&a[i]);
        }
        merge_sort(1,n);
        for(int i=1;i<=n;i++){
            printf("%d ",a[i]);
        }
        puts("");
    }
    return 0;
}

应该是很好懂的,归并排序难在了合并两部分的值那里。
左右两部分的起点肯定是它们那部分的最小值,因为已经处理好了,然后我们去比较这两部分内的最小值,依次加入temp数组,最后在当前区间[l,r]之间依次赋值,这样区间就是有序的了,然后在返回上一层继续重复


对比快排

与快排相比,快排是从当前区间随便选取一个基准,把小于基准的放左边,大于基准的放右边,处理完后继续递归。

而归并是选取当前区间中点,一直递归到只有两个数字,然后合并这个区间,递归返回上一层,继续合并。

快排是先处理在递归,归并是先递归在处理。


时间复杂度

每次所有小区间的处理加起来其实就是扫了一遍这个数组,O(n)
然后归并是一半一半处理的,等于进行了logn次的合并,所以时间复杂度是O(nlogn)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我不会c语言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值