当前位置: 首页 > news >正文

归并排序(Merge Sort)(递归写法)

归并排序(Merge Sort)知识点

1. 基本思想

归并排序是一种分治算法(Divide and Conquer),其核心思想是:

  1. 分解(Divide):将待排序的数组递归地分成两个子数组,直到每个子数组只包含一个元素(此时自然有序)。

  2. 合并(Merge):将两个已排序的子数组合并成一个有序的数组,直到所有子数组合并完成,最终得到完整的有序数组。

2. 算法步骤
  • 递归分解

    • 计算数组的中间位置 mid,将数组分为左半部分 [left, mid] 和右半部分 [mid+1, right]

    • 递归地对左半部分和右半部分进行归并排序。

  • 合并有序子数组

    • 使用双指针法,比较左右两个子数组的元素,按顺序合并到一个临时数组中。

    • 将临时数组中的结果复制回原数组的对应位置。

3. 时间复杂度
  • 最优、最差、平均时间复杂度均为 O(n log n)

    • 分解过程是 O(log n)(递归深度)。

    • 合并过程是 O(n)(每次合并需要线性时间)。

  • 空间复杂度 O(n)

    • 需要一个临时数组存储合并后的结果。

4. 稳定性
  • 归并排序是稳定的,因为在合并时,如果两个元素相等,可以优先取左子数组的元素,保持它们的相对顺序。

5. 适用场景
  • 适用于大数据量的排序,因为它的时间复杂度稳定在 O(n log n)

  • 适用于链表排序,因为归并排序对数据的随机访问要求较低(相比快速排序)。

代码 

//归并排序
//子函数
void _MergeSort(int* num, int* temp, int begin, int end)
{
//不断二分使有序(最小子问题是两个区间,每个区间各一个,然后归并)
if (begin >= end) //也可以==,因为底下的区间分发注定begin不会大于end,只会等于
return;
int mid = (begin + end) / 2; //二分取中间
_MergeSort(num, temp, begin, mid); //必须这样分区间[begin , mid] [mid + 1 , end] 不然就会栈溢出
_MergeSort(num, temp, mid + 1, end);
//归并

//分左区间
int begin1 = begin;
int end1 = mid;
//分右区间
int begin2 = mid + 1;
int end2 = end;

    int i = begin;
while (begin1 <= end1 && begin2 <= end2)
{
if (num[begin1] < num[begin2])
{
temp[i++] = num[begin1++];
}
else
{
temp[i++] = num[begin2++];
}
}
//处理num余下元素
while (begin1 <= end1)
{
temp[i++] = num[begin1++];
}
while (begin2 <= end2)
{
temp[i++] = num[begin2++];
}
//循环一次就赋一次值, 当然也可以整体赋,但是会很麻烦,这样写不麻烦,推荐这样写
memcpy(num + begin, temp + begin, (end - begin + 1) * sizeof(int)); 
}
//根函数
void MergeSort(int* num, int n)
{
int* temp = (int*)malloc(sizeof(int) * n);
if (temp == NULL)
{
perror("malloc");
exit(1);
}
_MergeSort(num, temp, 0, n - 1);
free(temp);
temp = NULL;
}

http://www.lryc.cn/news/595657.html

相关文章:

  • 【前端】ikun-pptx编辑器前瞻问题一: pptx的xml样式, 使用html能100%还原么
  • vscode目录,右键菜单加入用VSCode打开文件和文件夹(快速解决)(含删除)(脚本)
  • 基于 KeepAlived + HAProxy 搭建 RabbitMQ 高可用负载均衡集群
  • 医院信息系统(HIS)切换实施方案与管理技术分析
  • Linux中信号认识及处理和硬件中断与软中断的讲解
  • 基于 Spring Batch 和 XXL-Job 的批处理任务实现
  • iOS加固工具有哪些?从零源码到深度混淆的全景解读
  • iOS 抓包工具有哪些?场景导向下的工具推荐与实战对比
  • 微软徽标认证是什么?如何快速获取驱动签名?
  • haproxy七层代理新手入门详解
  • 字体识别实战:用Python打造智能字体侦探工具
  • 查看 iOS iPhone 设备上 App 和系统运行时的实时日志与崩溃日志
  • 一文速通《线性方程组》
  • ipynb断点不停 ipynb调试相关
  • 项目集成zustand后,如何构建和使用,以及devtools函数。
  • 报错error:0308010C:digital envelope routines::unsupported解决方案
  • 网络原理 HTTP 和 HTTPS
  • 【3GPP】5G专用词汇1
  • 开源AI智能客服、AI智能名片与S2B2C商城小程序在客户复购与转介绍中的协同效应研究
  • 智联智造:国内新能源汽车品牌AGV小车无线控制系统创新实践
  • 《C++初阶之STL》【string类:详解 + 实现】
  • python办自动化--读取邮箱中特定的邮件,并下载特定的附件
  • 在Android开发中,如何获取到手机设备的PIN码?
  • 使用python中的pymysql库,并且转化为数组元组数据
  • 重构创作边界:川翔云电脑 - UE5云端超算引擎​
  • mysql_innodb_cluster_metadata源数据库
  • 7.22总结mstp,vrrp
  • 如何给手机充电才不伤电池?
  • Selenium+Java 自动化测试入门到实践:从环境搭建到元素操作
  • STM32 GPIO(通用输入输出)详解:从模式原理到实战应用