归并排序:

(复制粘贴百度百科没什么意思),简单来说,就是对数组进行分组,然后分组进行排序,排序完最后再整合起来排序!

我看了很多博客,都是写的8个数据呀什么的(2^4,分组方便),我就想着,要是10个数据呢,他们那种就没怎么讲清楚,下面我来讲一下我所理解的归并排序!

思路整理如下所示:

下面用代码来实现(代码注释超详细):

用来判断整合几次的最外层循环!

void MergeSort(int *arr, int len) //这块用了函数调用  当然你给上面那玩意写到这个里面完全可以
{for(int i=1; i<len; i*=2)//首先来看假如数组有八位满足不满足条件 (2^3)<8不成立 也就是四四合并之后   就完成了合并  查看上面图 满足条件//再来看假如有10个值  (2^4)<10不成立   也就是八八合并之后  需要四次合并  查看上图  满足条件{Merge(arr, len, i); //调用函数主体   直接写到这个循环中也完全ok}
}

函数主体:

//8 6 3 2 7 1 9 5 4 0
//如上所示 单个数的时候 L1 = H1就是这个数字本身
//68  23  17  59  04
//这块拿前两个分好的数组为例 arr[L1] = 6  arr[H1] = 8  arr[L2] = 2  arr[H2] = 3
//2368    1579    04
//拿这组举例的话  arr[L1] = 2  arr[H1] = 8   arr[L2] = 1   arr[H2] = 9
//12356789    04
//arr[L1] = 1   arr[H1] = 9   arr[L2] = 0   arr[H2] = 4
void Merge(int* arr, int len, int gap)
{//数组本身空间不够,这块早堆区申请一个和数组等长的动态内存int* brr = (int*)malloc(sizeof(int) * len);assert(brr != NULL);//int L1 = 0;   //这块就到归并排序的精髓了   假设第一步,gap的值是1  一一合并L1 = 0  H1 = 0int H1 = L1 + gap - 1;  //接上行 合并之后L1 = 0,H1 = 1int L2 = H1 + 1;    //到这儿之后  按照上图来说68 23   arr[L1] = 6  arr[H1] = 8;int H2 = L2 + gap - 1 < len ? L2 + gap - 1 : len - 1;//那么arr[L2] = 2   arr[H2] = 3 ; L2 = H1 + 1 = 2 ; //H2 = L2 + gap - 1 < len ? L2 + gap - 1 : len - 1 = 3;这里写个三目运算符主要是用来判断L2+gap如果越界len的话,那么H2的下标值为len-1int i = 0;// 堆区申请来的空间brr存放数据的下标while (L2 < len)     //这块为什么要L2 < len 呢 先想一下 如果用L1 H1的话 跑到后期 L2早就越界了导致左边的白跑{                    //然后使用L2的时候可以保证右边的数组最少取到一个值  使用H2的话会导致提前越界  导致有些数据不能成功排序while (L1 < H1 && L2 < H2){if (arr[L1] <= arr[L2]){brr[i++] = arr[L1++]; //这块后置++的原因是先用再加 难以理解的话可以写成下面这种/*brr[i] = arr[L1];i++, L1++;*/}else{brr[i++] = arr[L2++];}}while (L1 <= H1)//因为上面的内层while中是 "&&" 可能其中一项满足 但是另外一项不满足  因此退出了while循环 因此写这么一句 {               //如果左边还有数据  挪下来brr[i++] = arr[L1++];}while (L2 <= H2)//如果右边组还有数据,挪下来{brr[i++] = arr[L2++];}L1 = H2 + 1;  //因为数据得遍历完分组排序  这是在新的分好的数组中的左值与右值  与上面一毛一样H1 = L1 + gap - 1;L2 = H1 + 1;H2 = L2 + gap - 1 < len ? L2 + gap - 1 : len - 1;}//这块退出while就是右边的arr中数组L2越界了(while(L2<len)) 此时右边肯定没有数据了//至于arr中左边的数组还有没有值  不确定再来个判断while (L1 < len){brr[i++] = arr[L1++];}//然后再将brr中数组导入到arr中即可  for (int i = 0; i < len; i++){arr[i] = brr[i];}free(brr); //堆区空间的释放
}

将代码写一块就是:

//8 6 3 2 7 1 9 5 4 0
//如上所示 单个数的时候 L1 = H1就是这个数字本身
//68  23  17  59  04
//这块拿前两个分好的数组为例 arr[L1] = 6  arr[H1] = 8  arr[L2] = 2  arr[H2] = 3
//2368    1579    04
//拿这组举例的话  arr[L1] = 2  arr[H1] = 8   arr[L2] = 1   arr[H2] = 9
//12356789    04
//arr[L1] = 1   arr[H1] = 9   arr[L2] = 0   arr[H2] = 4
void Merge(int* arr, int len, int gap)
{//数组本身空间不够,这块早堆区申请一个和数组等长的动态内存int* brr = (int*)malloc(sizeof(int) * len);assert(brr != NULL);//int L1 = 0;   //这块就到归并排序的精髓了   假设第一步,gap的值是1  一一合并L1 = 0  H1 = 0int H1 = L1 + gap - 1;  //接上行 合并之后L1 = 0,H1 = 1int L2 = H1 + 1;    //到这儿之后  按照上图来说68 23   arr[L1] = 6  arr[H1] = 8;int H2 = L2 + gap - 1 < len ? L2 + gap - 1 : len - 1;//那么arr[L2] = 2   arr[H2] = 3 ; L2 = H1 + 1 = 2 ; //H2 = L2 + gap - 1 < len ? L2 + gap - 1 : len - 1 = 3;这里写个三目运算符主要是用来判断L2+gap如果越界len的话,那么H2的下标值为len-1int i = 0;// 堆区申请来的空间brr存放数据的下标while (L2 < len)     //这块为什么要L2 < len 呢 先想一下 如果用L1 H1的话 跑到后期 L2早就越界了导致左边的白跑{                    //然后使用L2的时候可以保证右边的数组最少取到一个值  使用H2的话会导致提前越界  导致有些数据不能成功排序while (L1 < H1 && L2 < H2){if (arr[L1] <= arr[L2]){brr[i++] = arr[L1++]; //这块后置++的原因是先用再加 难以理解的话可以写成下面这种/*brr[i] = arr[L1];i++, L1++;*/}else{brr[i++] = arr[L2++];}}while (L1 <= H1)//因为上面的内层while中是 "&&" 可能其中一项满足 但是另外一项不满足  因此退出了while循环 因此写这么一句 {               //如果左边还有数据  挪下来brr[i++] = arr[L1++];}while (L2 <= H2)//如果右边组还有数据,挪下来{brr[i++] = arr[L2++];}L1 = H2 + 1;  //因为数据得遍历完分组排序  这是在新的分好的数组中的左值与右值  与上面一毛一样H1 = L1 + gap - 1;L2 = H1 + 1;H2 = L2 + gap - 1 < len ? L2 + gap - 1 : len - 1;}//这块退出while就是右边的arr中数组L2越界了(while(L2<len)) 此时右边肯定没有数据了//至于arr中左边的数组还有没有值  不确定再来个判断while (L1 < len){brr[i++] = arr[L1++];}//然后再将brr中数组导入到arr中即可  for (int i = 0; i < len; i++){arr[i] = brr[i];}free(brr); //堆区空间的释放
}void MergeSort(int *arr, int len) //这块用了函数调用  当然你给上面那玩意写到这个里面完全可以
{for(int i=1; i<len; i*=2)//首先来看假如数组有八位满足不满足条件 (2^3)<8不成立 也就是四四合并之后   就完成了合并  查看上面图 满足条件//再来看假如有10个值  (2^4)<10不成立   也就是八八合并之后  需要四次合并  查看上图  满足条件{Merge(arr, len, i); //调用函数主体   直接写到这个循环中也完全ok}
}

主要就是H2的取值怎么取值和思路是重点那块是重点!

“但凡辛苦,皆是礼物”

归并排序(代码注释超详细)相关推荐

  1. TCP协议的服务器与客户端的程序设计(代码注释超详细)

    在上篇博客中讲到了三次握手和四次挥手: Linux网络编程--TCP中的三次握手和四次挥手_神厨小福贵!的博客-CSDN博客服务器编程和客户端编程的大致流程如下:三次握手是在客户端中的connect中 ...

  2. Java菜鸟笔记:Java猜字母游戏完整代码 注释超详细(三次机会,计算总分,可运行)

    import java.util.Scanner; import java.util.regex.Pattern; /*** 猜字母游戏,程序随机生成一个五个长度不重复的字母数组,要求用户也输入五个字 ...

  3. 学习pandas全套代码【超详细】数据查看、输入输出、选取、集成、清洗、转换、重塑、数学和统计方法、排序

    大家早上好,本人姓吴,如果觉得文章写得还行的话也可以叫我吴老师.欢迎大家跟我一起走进数据分析的世界,一起学习! 感兴趣的朋友可以关注我的数据分析专栏,里面有许多优质的文章跟大家分享哦. 本篇博客将会给 ...

  4. 400 多行代码!超详细 Rasa 中文聊天机器人开发指南 | 原力计划

    作者 | 无名之辈FTER 责编 | 夕颜 出品 | 程序人生(ID:coder_life) 本文翻译自Rasa官方文档,并融合了自己的理解和项目实战,同时对文档中涉及到的技术点进行了一定程度的扩展, ...

  5. Github上传代码菜鸟超详细教程

    最近需要将课设代码上传到Github上,之前只是用来fork别人的代码. 这篇文章写得是windows下的使用方法. 第一步:创建Github新账户 第二步:新建仓库 第三部:填写名称,简介(可选), ...

  6. 用Kotlin语言开发玩安卓,基于基于Material Design+AndroidX + MVP + RxJava + Retrofit等优秀的开源框架开发,注释超详细,方便大家练手

    WanAndroid 一位练习时长两年半的安卓练习生根据鸿神提供的WanAndroid开放Api来制作的产品级App,基本实现了所有的功能,使用Kotlin语言,基于Material Design+A ...

  7. win10环境下下载安装openpose(only cpu)并在pycharm中运行代码(超详细)

    win10环境下下载安装openpose(only cpu)并在pycharm中运行代码(超详细) (一)前言 (二)准备工作 (三)友情提醒 (四)详细安装步骤 1.新建文件夹 2.下载OpenPo ...

  8. Deep Learning:基于pytorch搭建神经网络的花朵种类识别项目(内涵完整文件和代码)—超详细完整实战教程

    基于pytorch的深度学习花朵种类识别项目完整教程(内涵完整文件和代码) 相关链接:: 超详细--CNN卷积神经网络教程(零基础到实战) 大白话pytorch基本知识点及语法+项目实战 文章目录 基 ...

  9. Git(2)-- Git安装后首次配置与第一次使用Git和Github管理自己的代码(超详细纯小白图文教程)

    文章目录 0.写在前面: 一.注册Github 1.注册Github: 2.登录 3.创建仓库 二.安装Git 三.配置Git和Github(Git安装好后首次使用需要配置完成后才可以使用) 1.打开 ...

最新文章

  1. Flink从Kafka 0.8中读取多个Topic时的问题
  2. 家校通Android源码,基于Android的家校通系统设计与实现
  3. 带有无参数的存储过程
  4. Change FZU - 2277(线段树+dfs序)
  5. element ui表单校验prop的链式写法----源码分析
  6. ajax jsonp img
  7. php curl 返回cookie_分享新浪图床上传接口PHP源码
  8. 浅谈公路工程项目管理的发展趋势
  9. 【FPGA基础】DDR的基本原理介绍,DDR快速上手使用
  10. 安装Win10 Ubuntu20.04双系统
  11. 使用 Eclipse TPTP 测试 Web 应用的方法与扩展
  12. 路飞项目整体流程(二)
  13. 面试官问“为什么应聘这个岗位”,应该如何回答?
  14. 任意用户注册任意用户密码修改
  15. java8-ZoneId
  16. 用原生js实现淘宝详情页图片放大镜效果
  17. MATLAB 信号与系统
  18. CVE-2010-2729(MS10-061)
  19. Bolt介绍及基于其的实例
  20. 阿里云前端专家冯军:前端用户体验该如何优化

热门文章

  1. TensorFlow简单线性回归
  2. 黎曼曲面Riemann Surface
  3. 2021年大数据Hadoop(十二):HDFS的API操作
  4. PHP 算法题:有多少苹果用来分赃1.1
  5. cmd怎么实现Java你好_java环境配置以及如何在cmd窗口运行java代码
  6. Android 签名配置
  7. Python记录-基础语法入门
  8. SqlSessionFactoryBean的构建流程
  9. PyTorch 笔记(19)— Tensor 用 GPU 加速
  10. Linux 磁盘挂载