网上很多归并排序文章都是主讲归并排序原理,但对于代码实现部分的见解没有很侧重,所以本章让我们一起来看一下归并算法的代码实现部分。

原理

学习一个算法,首先当然得学习它的原理啦~

归并排序,利用分治法的思想,先将数组折半分组,直至每组只剩一个元素,然后排序合并数组,最终使其变为完全有序数组。

上动画演示,这里引用 “五分钟学算法” up主的动图,觉得不错

动画演示虽是同时分组,但当你调试代码时,你会发现它是先分完一边,再分另一边

还有一张图片我觉得也蛮不错的,很好的体现出分治法的思想。

代码实现

先看一下合并(merge)部分的实现

void merge(int low,int mid,int high)
{int left = low;   //左边部分数组指针int right = mid + 1;    //右边部分指针int k = low;   //对temp数组进行操作的指针while (left < mid + 1 && right < high + 1) {  /*这个while是用来将两个数组合并成一个新的                          数组的,该数组暂时存放在temp[]里面*/if (nums[left] > nums[right]) {temp[k++] = nums[right++];  //这里的k++和right++意思是先赋值后加1}                              //相当于下面else的写法啦else {temp[k] = nums[left];k++;left++;}}//查看左边序列是否为空while (left < mid + 1) {        /*这两个while是当一个数组的值存放完毕时,将另一个数组剩余                                         的元素依次存入*/temp[k++] = nums[left++];}//查看右边序列是否为空while (right < high + 1) {temp[k++] = nums[right++];}//移动回原数组,num[i]是定义在全局区待排序的数组for (int i = low; i <= high; i++) {    //这里要i=low阿,不可以等于0nums[i] = temp[i];}
}

分组(mergeSort)部分的代码实现

void mergeSort(int low,int high) //运用递归啦
{if(low >= high) {  //相当于是单个元素一组了,直接返回就行return;}int mid = low + ((high - low) >> 1);/*防止low和high太大导致越界,>>1和除以2一样,不过  比/2效率快*///分mergeSort(low, mid); //先分左边mergeSort(mid + 1, high);    //分完左边分右边//治merge(low, mid, high);  //一层一层合并,小数组逐渐合并成大数组
}

最后看一下完整的具体代码

#include <iostream>
using namespace std;int nums[7] = { 7,3,5,2,9,8 };//待排序数组
int temp[7];//临时存储数组void merge(int low,int mid,int high)
{int left = low;   //左边部分数组指针int right = mid + 1;    //右边部分指针int k = low;   //对temp数组进行操作的指针while (left < mid + 1 && right < high + 1) {if (nums[left] > nums[right]) {temp[k++] = nums[right++];}else {temp[k] = nums[left];k++;left++;}}//查看左边序列是否为空while (left < mid + 1) {temp[k++] = nums[left++];}//查看右边序列是否为空while (right < high + 1) {temp[k++] = nums[right++];}//移动回原数组for (int i = low; i <= high; i++) {  //这里要i=low阿,不可以等于0nums[i] = temp[i];}
}void mergeSort(int low,int high)
{if(low >= high) {return;}int mid = low + ((high - low) >> 1);//防止low和high太大导致越界,>>1和除以2一样,不过比/2效率快//分mergeSort(low, mid);mergeSort(mid + 1, high);//治merge(low, mid, high);
}int main()
{mergeSort(0, 5);for (int i = 0; i <=5; i++) {cout << nums[i] << " ";}cout << endl;return 0;
}

最好是可以自己调试一下代码,看一下变量值的变化,会对归并算法的实现更加清晰明了。

复杂度分析

  • 时间复杂度:

    从这个递归树可以看出,第一层时间代价为cn,第二层时间代价为cn/2+cn/2=cn……每一层代价都是cn,总共有logn+1层,所以总的时间代价为cn*(logn+1).时间复杂度是O(nlogn).

  • 空间复杂度: 归并排序算法排序过程中需要额外的一个序列temp[] 去存储排序后的结果,所占空间是n,因此空间复杂度为O(n)

  • 稳定性: 在最坏、最佳、平均情况下归并排序时间复杂度均为O(nlogn).从合并过程中可以看出合并排序稳定。

小结:

归并排序算法的效率高,因为它的时间复杂度只有O(nlogn),所以当处理的数据量多的时候,用归并排序是一个不错的选择。对于该算法中的分治思想不太了解的C友可以先查一下概念,而后借助调试帮助理解代码实现。

归并排序(详解代码实现)相关推荐

  1. 归并排序详解(Acwing 归并排序y总模板)

    归并排序详解 文章目录 归并排序过程 demo(完整y总模板) 结束语 每个人心里都有一团火,路过的人却只看见了烟.加油xdm!!! 归并排序过程 基础知识:我们知道归并排序也是一种基于分治法思想的排 ...

  2. 归并排序过程实现c语言,C语言归并排序详解

    C语言归并排序详解 发布日期:2015-12-31 11:16 来源: 标签: 编程语言 C教程 C语言归并排序 C语言归并排序算法 本章我们主要学习C语言实现排序算法之归并排序,对归并排序的原理及实 ...

  3. 归并排序详解(python实现)

    归并排序详解(python实现) 因为上个星期leetcode的一道题(Median of Two Sorted Arrays)所以想仔细了解一下归并排序的实现.

  4. 五分钟搞懂后缀数组!后缀数组解析以及应用(附详解代码)

    为什么学后缀数组 后缀数组是一个比较强大的处理字符串的算法,是有关字符串的基础算法,所以必须掌握. 学会后缀自动机(SAM)就不用学后缀数组(SA)了?不,虽然SAM看起来更为强大和全面,但是有些SA ...

  5. 『ML笔记』HOG特征提取原理详解+代码

    HOG特征提取原理详解+代码! 文章目录 一. HOG特征介绍 二. HOG算法具体流程+代码 2.1. 图像灰度化和gamma矫正 2.2. 计算图像像素梯度图 2.3. 在8×8的网格中计算梯度直 ...

  6. 【嵌入式开发】 Bootloader 详解 ( 代码环境 | ARM 启动流程 | uboot 工作流程 | 架构设计)

    作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42462795 转载请著名出处 相关资源下载 :  -- u-boo ...

  7. xvid 详解 代码分析 编译等

    1.   Xvid参数详解 众所周知,Mencoder以其极高的压缩速率和不错的画质赢得了很多朋友的认同! 原来用Mencoder压缩Xvid的AVI都是使用Xvid编码器的默认设置,现在我来给大家冲 ...

  8. 23种设计模式详解(代码讲解、持续更新)

    目录 设计模式分类 设计模式的六大原则 创建型模式 1.工厂方法模式(Factory Method) 2.建造者模式(Builder Pattern(常用.常见)) 行为型模式 模板模式(Templa ...

  9. iOS 内购详解-代码篇

    内购项目-代码篇 一.分步骤说明 1.获取商品列表 2.苹果服务器返回的可购买商品 3.下单购买商品 4.购买队列状态变化,判断购买状态是否成功 5.交易验证 6.拿到的收据信息是,此App所有购买的 ...

  10. 【Android】Listview返回顶部,快速返回顶部的功能实现,详解代码。

    2019独角兽企业重金招聘Python工程师标准>>> 作者:程序员小冰,GitHub主页:https://github.com/QQ986945193 新浪微博:http://we ...

最新文章

  1. 用python语言调试程序你用的平台是_Python 程序如何高效地调试?
  2. AngularJs详细
  3. 如何确保SAP OData服务的返回结构为JSON格式
  4. 大数据学习系列----基于Spark Streaming流式计算
  5. 143. 最大异或对
  6. tomcat配置自动服务器地址,修改eclipse部署tomcat时服务器部署地址
  7. WEB字体,多列布局和伸缩盒
  8. Photoshop CS5的序列号
  9. android-Vibrator的使用
  10. 【深入浅出精华版视频】-刘意day13思维导图整理
  11. 用MATLAB画出双极性NRZ,[工学]通信原理MATLAB仿真教程第7章.ppt
  12. 奇虎周鸿祎:创业者不要太偏执
  13. 基于可变部件模型(DPM)的车辆行人检测
  14. 使用awk处理多行fasta文件拆分为单个fasta文件,并去掉后缀^M
  15. 小程序云开发实现微信支付完整代码
  16. 罚函数 c语言,神题求解............
  17. b树的表示形式_B.Com的完整形式是什么?
  18. 揭秘:广告拦截软件如何赚钱?
  19. 计算机视觉sci需要什么水平论文,计算机视觉博士一般几篇论文_林达华博士_林达华视觉...
  20. mac版mysql初始密码忘记,重置密码

热门文章

  1. PHP接口API文档转换SDK【神器】
  2. 办理登机的英语词组手机键盘_如何使用智能手机使登机轻而易举
  3. Java面试题2019
  4. 本文主要讲述如何开通自己的博客。若读者不想或已经知道如何开通使用博客,那么就可以跳过。 一直以来,想把自己在学习过程中遇到的问题及解决办法共享给志同道合的人,那么如何分享自己的见解呢?有如下方法
  5. 二.android 12 修改文件夹背景透明度
  6. 初始化Direct3D
  7. 神经网络Loss损失函数总结
  8. vsc 好用的插件
  9. 基于JavaGUI的火锅自助点菜客户端和服务端系统
  10. 给windows电脑重装系统