【递归版】归并排序算法(1)

简介: 【递归版】归并排序算法(1)



MergeSort归并排序

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

归并排序核心步骤:分解+合并

归并排序的特性总结:

1. 归并的缺点在于需要O(N)的空间复杂度,归并排序的思考是解决在磁盘中的外排序问题。
2. 时间复杂度:O(N*logN)
3. 空间复杂度:O(N)
4. 稳定性:稳定

对于两端有序序列的合并,在顺序表和链表的OJ题目都学习过了。


整体思想

整体思想

  • 分治的思想(分而治之)分治的思想一般都用递归的方式去完成。
  • 两个有序序列合并任然是有序序列
  • 一段无序序列>>>>>>有序
  • 无序序列一直【递推】分割分割直到一个元素(一个元素肯定有序)
  • 再【回归】的时候合并即可
  • 递归的两部分:子问题&结束条件

整个流程

  • 开辟一个tmp新的数组在外部(不可能每次递归都开辟一个新的数组)
  • 开始分解[begin,mid] [mid+1,end]
  • 分解到不能在分解了(只有一个元素肯定是顺序序列)回归begin = end
  • 合并
  • 两个有序序列数组和链表合并,依旧有序(取小值尾插)
  • 有序序列合并(归并有序序列)
  1. 利用开辟一个tmp新的数组(不能放到MergeSort函数里面,不可能每次递归都开辟一个新的数组)
  2. 选小的尾插直到至少序列begin > end
  3. 若还有序列存在元素直接尾插到tmp后面
  • 拷贝到a数组
  • 最后记住释放free(tmp)❗

重点突破

  • 递归的分解
  • 有序序列的合并
  • tmp数组的开辟

易错点突破

  • 有序序列的合并(&&)
  • 拷贝的起始位置
  • 下标和元素个数和区间问题

图解分析

代码实现

void _MergeSort(int* a, int* tmp,int begin, int end)
{
  if (begin >= end)
  {
    return;
  }
  //分割
  int mid = (begin + end) / 2;
  //[begin,mid] [mid+1 ,end]
  _MergeSort(a, tmp, begin, mid);
  _MergeSort(a, tmp, mid + 1, end);
  //合并
  int begin1 = begin;
  int end1 = mid;
  int begin2 = mid + 1;
  int end2 = end;
  int i = begin;
  //int i = 0;
  while (begin1 <= end1 && begin2 <= end2)
  {
    if (a[begin1] < a[begin2])
    {
      tmp[i++] = a[begin1++];
    }
    else//>
    {
      tmp[i++] = a[begin2++];
    }
  }
  while (begin1 <= end1)//
  {
    tmp[i++] = a[begin1++];
  }
  while (begin2 <= end2)
  {
    tmp[i++] = a[begin2++];
  }
  //合并完成拷贝
  //memcpy(a + begin, tmp, (end - begin + 1) * sizeof(int));
  memcpy(a + begin, tmp+begin, (end - begin + 1) * sizeof(int));
}
void MergeSort(int* a, int n)
{
  int* tmp = (int*)malloc(sizeof(int) * n);
  if (tmp == NULL)
  {
    perror("malloc fail");
    return;
  }
  _MergeSort(a, tmp, 0, n - 1);
  free(tmp);
}

时间复杂度

时间复杂度O(N*logN)

递归&归并排序VS快速排序

  • 快速排序的递归:前序递归
  • 归并排序的递归 :后序递归

🙂感谢大家的阅读,若有错误和不足,欢迎指正。

目录
相关文章
|
2月前
|
算法 Python
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果;贪心算法在每一步选择局部最优解,追求全局最优;动态规划通过保存子问题的解,避免重复计算,确保全局最优。这三种算法各具特色,适用于不同类型的问题,合理选择能显著提升编程效率。
70 2
|
3月前
|
算法 搜索推荐 Shell
数据结构与算法学习十二:希尔排序、快速排序(递归、好理解)、归并排序(递归、难理解)
这篇文章介绍了希尔排序、快速排序和归并排序三种排序算法的基本概念、实现思路、代码实现及其测试结果。
65 1
|
3月前
|
算法 定位技术
数据结构与算法学习九:学习递归。递归的经典实例:打印问题、阶乘问题、递归-迷宫问题、八皇后问题
本文详细介绍了递归的概念、重要规则、形式,并展示了递归在解决打印问题、阶乘问题、迷宫问题和八皇后问题等经典实例中的应用。
64 0
|
3月前
|
存储 搜索推荐 算法
【排序算法(二)】——冒泡排序、快速排序和归并排序—>深层解析
【排序算法(二)】——冒泡排序、快速排序和归并排序—>深层解析
|
3月前
|
存储 算法 搜索推荐
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
89 0
|
3月前
|
搜索推荐 Java Go
深入了解归并排序算法
深入了解归并排序算法
54 0
|
5月前
|
算法 搜索推荐 Java
算法实战:手写归并排序,让复杂排序变简单!
归并排序是一种基于“分治法”的经典算法,通过递归分割和合并数组,实现O(n log n)的高效排序。本文将通过Java手写代码,详细讲解归并排序的原理及实现,帮助你快速掌握这一实用算法。
56 0
|
5月前
|
数据采集 搜索推荐 算法
【高手进阶】Java排序算法:从零到精通——揭秘冒泡、快速、归并排序的原理与实战应用,让你的代码效率飙升!
【8月更文挑战第21天】Java排序算法是编程基础的重要部分,在算法设计与分析及实际开发中不可或缺。本文介绍内部排序算法,包括简单的冒泡排序及其逐步优化至高效的快速排序和稳定的归并排序,并提供了每种算法的Java实现示例。此外,还探讨了排序算法在电子商务、搜索引擎和数据分析等领域的广泛应用,帮助读者更好地理解和应用这些算法。
54 0
|
5月前
|
算法
【算法】递归总结:循环与递归的区别?递归与深搜的关系?
【算法】递归总结:循环与递归的区别?递归与深搜的关系?
130 0
|
1天前
|
算法 数据安全/隐私保护 计算机视觉
基于Retinex算法的图像去雾matlab仿真
本项目展示了基于Retinex算法的图像去雾技术。完整程序运行效果无水印,使用Matlab2022a开发。核心代码包含详细中文注释和操作步骤视频。Retinex理论由Edwin Land提出,旨在分离图像的光照和反射分量,增强图像对比度、颜色和细节,尤其在雾天条件下表现优异,有效解决图像去雾问题。

热门文章

最新文章