首页 > 编程语言 >排序算法-归并排序

排序算法-归并排序

时间:2024-02-23 17:13:10浏览次数:31  
标签:归并 int 分离 合并 mid 算法 数组 排序 指针

时空复杂度

时间复杂度:O(nlogn) 空间复杂度:O(n) 使用了分治思想

优势

1.稳定

归并的时空复杂度非常稳定的,不论是在哪种情况下,归并算法的时间复杂度都不变,

2.高效

归并算法计算效率相比其他算法也是非常快的  

思路图解

把一个有n个元素的数组,分成n个有1个元素的数组 然后边比较边合并

合并子序列 需要将两个已经有序的子序列合并成一个有序序列 双指针依次比较,小的数先进入结果数组,进入后指针后移 直到所有数字都进入结果数组  

函数组成

1.分离函数

使用递归,将数组分离到原子化 停止递归条件:x>=y,数组段已分离到只有一个元素 这里不开辟新数组来灌装,而是使用两个头尾index序号来表示分出的数组段 将数组段传入合并函数时,也是使用头尾序号的形式
void mergesort(int x,int y)  //分离函数,参数x和y分别代表要分离数组段的开头和结尾
{
        if (x>=y) return; //如果开头≥结尾,说明数组段已分离到只有一个元素,返回,停止分离
        
        int mid=(x+y)/2;            //将中间数求出来,用中间数把数列分成两段
        mergesort(x,mid);          //递归,继续分离分出的上半段
        mergesort(mid+1,y);        //递归,继续分离分出的下半段
        
        merge(x,mid,y);          //分离结束,进行合并函数
}

2.合并函数

由于没有开辟新的数组 需要合并的数组段在原数组序列中是紧挨在一起的,所以用三个参数index可表示两个数组段 第一段:low~mid,第二段:mid+1~high 合并是需要将两个无序数组段合并为一段有序数组 用两个指针 i、j,放在两段序列的开头,比较所指对象,较小的先进入结果数组,然后进入结果的指针后移 使用递归进行合并 结束条件: 两个数组的比较指针i、j 都已移动到数组结尾(i = mid和 j = high) 未达到结束条件就继续递归调用本函数或使用循环
void merge(int low,int mid,int high) //归并
//low 和 mid是要合并的第一个数列的开头和结尾,mid+1 和 high是第二个数列的开头和结尾
{
        vector<int> ans(n); //用来合并的临时数组,合并完成后灌装进原数组
        int i=low,j=mid+1,k=low;  //两个比较指针,一个结果输入指针
        while (i<=mid && j<=high)    //如果两个数列的数都没放完,循环
        {
                if (a[i]<a[j]) //若后者大于前者
                        ans[k++]=a[i++];  //后者入答案数组,且后指针与档案指针后移一格
                        //k++:先赋值,再加一
                else           //若前者大于前者
                        ans[k++]=a[j++];   //前者入答案数组,且前指针与档案指针后移一格
        }        //k++:先赋值,再增加
        while (i<=mid)   //若一个数列已放完,前数组还没放玩,就把剩下的都塞进结果数组
                ans[k++]=a[i++];
        while (j<=high)  //若一个数列已放完,后数组还没放玩,就把剩下的都塞进结果数组
                ans[k++]=a[j++];   
        for (int i=low;i<=high;i++)
                a[i]=ans[i];   //将排好的结果数组灌装入原数组的位置
 

标签:归并,int,分离,合并,mid,算法,数组,排序,指针
From: https://www.cnblogs.com/jk-2048/p/18029970

相关文章

  • [几何算法]任意多边形求面积
    求任意平面多边形的面积通过鞋带定理,在已知多边形各顶点的情况下,可以快速计算出其面积问题分析设一个多边形顶点按逆时针或顺时针顺序为$$P_1(x_1,y_1),P_2(x_2,y_2),\ldots,P_n(x_n,y_n)$$,其中$$P_1=P_{n+1}$$(首尾相连形成闭合多边形)。根据鞋带定理,该多边形的......
  • 基于yolov2深度学习网络的车辆行人检测算法matlab仿真
    1.算法运行效果图预览   2.算法运行软件版本MATLAB2022a 3.算法理论概述      近年来,深度学习在计算机视觉领域取得了显著成果,特别是在目标检测任务中。YOLO(YouOnlyLookOnce)系列算法作为其中的代表,以其高效和实时的性能受到广泛关注。YOLOv2,作为YOL......
  • 基于WIFI指纹的室内定位算法matlab仿真
    1.算法运行效果图预览  2.算法运行软件版本matlab2022a 3.算法理论概述        随着移动互联网和物联网技术的飞速发展,位置服务(LBS)已成为许多应用的核心功能,如导航、社交网络和智能物流等。室外定位技术,如全球定位系统(GPS),已相当成熟并广泛应用。然而,由于建......
  • 类欧几里得算法
    要求类似于这样的东西:\[\begin{align*}f(n,a,b,c)&=\sum\limits_{i=0}^n{\left\lfloor\frac{ai+b}{c}\right\rfloor}\\g(n,a,b,c)&=\sum\limits_{i=0}^n{\left\lfloor\frac{ai+b}{c}\right\rfloor}^2\\h(n,a,b,c)&=\sum\limits_{i=0}^......
  • day41 动态规划part3 代码随想录算法训练营 96. 不同的二叉搜索树
    题目:96.不同的二叉搜索树我的感悟:这题,考的概率不大,听一遍,过一遍就行。理解难点:二叉搜索树定义为什么是累加的听课笔记:代码示例:classSolution:defnumTrees(self,n:int)->int:dp=[0]*(n+1)#创建一个长度为n+1的数组,初始化为0d......
  • day40 动态规划part3 代码随想录算法训练营 343. 整数拆分
    题目:343.整数拆分我的感悟:题目很难,但我动力十足!!理解难点:如何拆分为什么要保留dp[i]听课笔记:代码示例:classSolution:defintegerBreak(self,n:int)->int:#思路:#dp[i]是到目前为止能拆分取的最大值#dp[i]可以拆成j*(集合)......
  • 十大经典排序算法
    十大经典排序算法.md0、算法概述0.1算法分类****十种常见排序算法可以分为两大类:比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间......
  • 文心一言 VS 讯飞星火 VS chatgpt (200)-- 算法导论15.2 4题
    四、用go语言,对输入链长度为n的矩阵链乘法问题,描述其子问题图:它包含多少个顶点?包含多少条边?这些边分别连接哪些顶点?文心一言:矩阵链乘法问题是一个经典的动态规划问题,其中给定一个矩阵链,我们需要确定一个乘法顺序,使得计算该链所需的总标量乘法次数最少。子问题图(也叫DAG,有......
  • 插入排序分析
    插入排序(升序)复杂度分析可以把插入排序想象成抽扑克牌,从牌堆中每抽一张牌我们就和手牌比较并插入。一般,我们习惯大牌放左边,小牌放右边,那么我们抽牌时从左往右(或从右往左)把抽的牌和手牌对比,找到,放入手牌,这个过程就可以看作时插入排序1.代码实现插入排序代码实现比较简单#in......
  • Python数据结构与算法05——快速排序
    快速排序:递归defquick_sort(aimlist,first,last):#打印当前排序状态print(aimlist)#如果子列表只有一个元素或没有元素,直接返回iffirst>=last:return#初始化低位、高位和中间值low=firstheigh=lastmid=aimli......