常见排序算法之归并排序——归并排序

简介: ​哈喽大家好,我是保护小周ღ,本期为大家带来的是常见排序算法中的归并排序,博主在这里先分享归并排序的递归算法,包您一看就会,快来试试吧~​

   image.gif编辑    

哈喽大家好,我是保护小周ღ,本期为大家带来的是常见排序算法中的归并排序,博主在这里先分享归并排序的递归算法,包您一看就会,快来试试吧~

image.gif编辑

image.gif编辑


目录

一、归并排序

1.1 基本思想

1.2 算法思想

1.3 程序设计思想

1.4 程序实现

1.5 归并排序的特性总结:


一、归并排序

1.1 基本思想

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法 (Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序 列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。


1.2 算法思想

image.gif编辑

到这里,我们可以得到一条结论,两个有序的子序列可以合成一个新的有序子序列,通过递归,我们两个新的有序序列也可以组成新的有序数列,最终实现排序的目的。有些朋友就会问了,这个我懂,关键是咋实现有序数列,其实非常的简单,分割递归至每个子序列只有一个元素时,是不是就有序啦,然后就可以合成有两个元素有序的列表嘛,再合成4个,8个……

image.gif编辑


1.3 程序设计思想

定义一个tmp数组,可以是动态开辟的(malloc),用于临时存放合并后的有序数据,定义_MergeSort()函数,用于分解,合并数据(递归实现),参数有,待处理数组,数据区间(数组下标),tmp数组。

    1. 判断区间是否存在,区间不存在以及只有一个元素的情况结束程序。
    2. 分割区间:mid=(left+right)/2;递归左右区间,分割递归至每个子序列只有一个元素。
    3. 每两个子序列一组,循环遍历每一个元素,if比较两个子序列各元素的大小,取大或取小,放入tmp数组,tmp[index++]=子序列++;直到有一个子序列遍历完,循环结束。
    4. 循环判断是子序列是否遍历完毕,未遍历完毕的子序列剩余元素直接给到tmp数组。
    5. 将tmp数组的对应的元素拷贝回原数组(已有序)。

    1.4 程序实现

    #define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>//动态开辟空间的函数的头文件void_MergeSort(int*a,intleft,intright,int*tmp)
    {
    //区间不存在以及只有一个元素的情况结束程序if (left>=right)
        {
    return;
        }
    intmid= (left+right) /2;
    //假设[left,mid],[mid+1,right]有序,那么我们就可以归并了//递归使左右区间有序//分割递归至每个子序列只有一个元素_MergeSort(a,left,mid,tmp);
    _MergeSort(a, mid+1,right, tmp);
    //归并intbegin1=left, end1=mid;
    intbegin2=mid+1, end2=right;
    intindex=left;
    while (begin1<=end1&&begin2<=end2)//有一个子序列遍历完,循环结束    {
    if (a[begin1] <a[begin2])//升序,取小        {
    tmp[index++] =a[begin1++];
            }
    else        {
    tmp[index++] =a[begin2++];
            }
        }
    //判断子序列是否遍历完,未遍历完毕的子序列剩余元素直接给到tmp数组while (begin1<=end1)
        {
    tmp[index++] =a[begin1++];
        }
    while (begin2<=end2)
        {
    tmp[index++] =a[begin2++];
        }
    //拷贝回去for (inti=left;i<=right;++i)
        {
    a[i] =tmp[i];
        }
    }
    //归并排序voidMergeSort(int*a,intn)
    {
    int*tmp=(int*)malloc(sizeof(int)*n);//动态开辟与待排序数组大小相等的一片连续的空间_MergeSort(a,0,n-1,tmp);//子函数实现归并free(tmp);//释放动态开辟的空间}
    //打印voidPrint(int*a, intn)
    {
    for (inti=0;i<n;++i)
        {
    printf("%d ",a[i]);
        }
    }
    intmain()
    {
    inta[] = {10,6,7,1,3,9,4,2};
    MergeSort(a,sizeof(a)/sizeof(a[0]));
    Print(a,sizeof(a)/sizeof(a[0]));
    return0;
    }

    image.gif

    image.gif编辑


    1.5 归并排序的特性总结:

    1. 归并的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问 题。

    2. 时间复杂度:O(N*logN)

    3. 空间复杂度:O(N)

    4. 稳定性:稳定


    至此归并排序的递归算法博主已经分享完了,相信大家对这个归并排序的逻辑有了一定的理解,大家可以自己动手敲敲代码,感受一下。

    image.gif编辑

    本期收录于博主的专栏——排序算法,适用于编程初学者,感兴趣的朋友们可以订阅,查看其它“常见排序”。排序算法_保护小周ღ的博客-CSDN博客

    感谢每一个观看本篇文章的朋友,更多精彩敬请期待:保护小周ღ ——归并排序非递归算法

    文章存在借鉴,如有侵权请联系修改删除!

    相关文章
    |
    6月前
    |
    机器学习/深度学习 算法 搜索推荐
    【初阶算法4】——归并排序的详解,及其归并排序的扩展
    【初阶算法4】——归并排序的详解,及其归并排序的扩展
    【初阶算法4】——归并排序的详解,及其归并排序的扩展
    |
    2月前
    |
    算法 搜索推荐 Shell
    数据结构与算法学习十二:希尔排序、快速排序(递归、好理解)、归并排序(递归、难理解)
    这篇文章介绍了希尔排序、快速排序和归并排序三种排序算法的基本概念、实现思路、代码实现及其测试结果。
    37 1
    |
    2月前
    |
    存储 搜索推荐 算法
    【排序算法(二)】——冒泡排序、快速排序和归并排序—>深层解析
    【排序算法(二)】——冒泡排序、快速排序和归并排序—>深层解析
    |
    2月前
    |
    存储 算法 搜索推荐
    算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
    算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
    82 0
    |
    2月前
    |
    搜索推荐 Java Go
    深入了解归并排序算法
    深入了解归并排序算法
    35 0
    |
    7月前
    |
    算法 前端开发 搜索推荐
    前端算法之归并排序
    前端算法之归并排序
    41 0
    |
    4月前
    |
    算法 搜索推荐 Java
    算法实战:手写归并排序,让复杂排序变简单!
    归并排序是一种基于“分治法”的经典算法,通过递归分割和合并数组,实现O(n log n)的高效排序。本文将通过Java手写代码,详细讲解归并排序的原理及实现,帮助你快速掌握这一实用算法。
    48 0
    |
    4月前
    |
    数据采集 搜索推荐 算法
    【高手进阶】Java排序算法:从零到精通——揭秘冒泡、快速、归并排序的原理与实战应用,让你的代码效率飙升!
    【8月更文挑战第21天】Java排序算法是编程基础的重要部分,在算法设计与分析及实际开发中不可或缺。本文介绍内部排序算法,包括简单的冒泡排序及其逐步优化至高效的快速排序和稳定的归并排序,并提供了每种算法的Java实现示例。此外,还探讨了排序算法在电子商务、搜索引擎和数据分析等领域的广泛应用,帮助读者更好地理解和应用这些算法。
    48 0
    |
    5月前
    |
    存储 算法 搜索推荐
    算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
    【7月更文挑战第12天】归并排序是高效稳定的排序算法,采用分治策略。Python 实现包括递归地分割数组及合并已排序部分。示例代码展示了如何将 `[12, 11, 13, 5, 6]` 分割并归并成有序数组 `[5, 6, 11, 12, 13]`。虽然 $O(n log n)$ 时间复杂度优秀,但需额外空间,适合大规模数据排序。对于小规模数据,可考虑其他算法。**
    80 4
    |
    5月前
    |
    算法 搜索推荐 C#