算法基础集训(第03天)------>【归并排序】:绝对是史上最全的归并排序分析,详细分析归并边界并给出算法可视化动图帮助你理解算法

20ed93c0f9974ca8baa4e93dceb7966d.gif

目录

一:概念定义

二:题目描述

三:算法详解

大致思路:

 边界分析:

 四:和快排代码的区别


一:概念定义

排序问题可以说是最经典的算法问题了,一般一开始学的基础算法就是排序,排序既是算法的基础,也是考研数据结构的重要知识点。但是 C/C++ 都有现成的库函数(C里是 qsort、C++是sort),所以导致很多人就没有学排序算法本身,其实排序算法的思路非常有意思,从最简单的学起,对以后学习复杂算法是非常有帮助的,比如快速排序和快速选择之间的关系,归并排序和逆序对之间的关系。
  从今天开始,我们来试着掌握每个排序算法的思路,今天是归并排序,归并排序和快速排序有异曲同工之妙,等会娓娓道来。
  归并排序,就是将两个有序的数组通过 “你来我往” 的方式合并成一个数组,如图:

图示含义
■蓝色的柱形代表尚未排好序的数
■ 红色的柱形代表已经排好序的数
其他颜色 ■ 的柱形正在递归、归并中的数

 31b6f42bc9b8405da640c20a80f81d76.gif


二:题目描述

给定你一个长度为 n 的整数数列,请你使用归并排序对这个数列按照从小到大进行排序。

并将排好序的数列按顺序输出。


三:算法详解

先给出个人多年使用的万能模板:

    #include<iostream>
    using namespace std;
    const int N=100010;
    int q[N],res[N];
    
    void mergesort(int q[],int l,int r)
    {
        //中点递归赋值
        if(l>=r) return ;
        int mid=(l+r)/2;
        mergesort(q,l,mid);
        mergesort(q,mid+1,r);
    
        int k=0,i=l,j=mid+1;//ij分别从两个有序数组头开始
        while(i<=mid&&j<=r)
        {
            if(q[i]<=q[j])  res[k++]=q[i++];
            else res[k++]=q[j++];
        }
        while(i<=mid) res[k++]=q[i++];
        while(j<=r) res[k++]=q[j++];
    
        for(int i=l,j=0;i<=r;i++,j++) q[i]=res[j];
    
    }
    
    
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&q[i]);
        }
        mergesort(q,0,n-1);
        for(int i=0;i<n;i++)
        {
            printf("%d ",q[i]);
        }
    
    }
    

大致思路:

1)将每对单个元素归并为 2个元素 的有序数组;
2)将 2个元素 的每对有序数组归并成 4个元素 的有序数组,重复这个过程…;
3)最后一步:归并 2 个 n / 2个元素的排序数组(为了简化讨论,假设n是偶数)以获得完全排序的 n 个元素数组。

注:「 递归 」是自顶向下的,实际上程序真正运行过程是自底向上「 回溯 」的过程

 边界分析:

mergesort(q,l,mid);mergesort(q,mid+1,r)的分界线能否改mergesort(q,l,mid-1);mergesort(q,mid,r)

显然可以,但是这时候需要改一改mid的值,因为mid=l+r>>1是向下取整,因此如果只有两个数字mid可能取到1,这会在递归的时候一半有用一半没用,而有用的一半和原来需要归并的范围都没变,因此会造成无限划分。解决方案:mid=l+r+1>>1(向上取整即可)

6d28ea02b33a4baab2b151159df4fc68.png


 四:和快排代码的区别

快速排序是先进行排序再划分递归子区间

归并排序是先划分到最小区间,然后再回溯排序

创作不易,建议点赞+收藏+关注,以免变成付费资源或者找不到宝贝文章了。 

基础集训结束后将开展拔高系列

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

代码kobe

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

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

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

打赏作者

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

抵扣说明:

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

余额充值