归并排序是典型分治思想的代表——首先把原问题分解为两个或多个子问题,然后求解子问题的解,最后使用子问题的解来构造出原问题的解。

对于归并排序,给定一个待排序的数组,首先把该数组划分为两个子数组,然后对子数组进行排序(递归调用归并排序),最后对两个有序的子数组进行合并,使合并之后的数组为有序状态。

让我们想想,把一个数组不断地划分为子数组,不断地划分......,不断地划分......., 最后停止了划分不下去了。 此时子数组的元素有一个,它们本身就是有序的。接下来,我们就需要执行合并过程,不断地一层层向上合并,........,  直到原数组。通过这个过程就会发现, 归并排序的核心在于合并有序的子数组,而不是对子数组进行排序,因为最底层的子数组本身就是有序的,上一层子数组如果想要变成有序的,通过合并底层有序的子数组就可以得到, 最终我们使原数组变成了有序的,从而完成了排序操作。

说明几点:

1. 归并排序采用了分治思想,它的核心在于合并子问题的解而不是求解子问题(快速排序也采用了分治思想,但它的核心是在于求解子问题而不需要合并子问题的解)、

2. 归并排序不是原址排序,它有排序过程中需要借助额外的内存空间。

3. 归并排序为稳定排序(其实呢,具体还得看你怎么写代码,如果两个数的值相等时,你不保持原顺序都就会变成非稳定的了)

4. 归并排序的时间复杂度为O(NlogN).

具体代码如下:

   /***********************************************************************
* Copyright (C) 2019 Yinheyi. <chinayinheyi@163.com>
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version. * Brief:
* Author: yinheyi
* Email: chinayinheyi@163.com
* Version: 1.0
* Created Time: 2019年05月06日 星期一 22时22分57秒
* Modifed Time: 2019年05月09日 星期四 21时10分59秒
* Blog: http://www.cnblogs.com/yinheyi
* Github: https://github.com/yinheyi
*
***********************************************************************/ // 归并排序,分治法的典型代表: 将原问题分解了几个子问题,解决子问题,再合并子问题的解,
// 这样就得到了原问题的解。
// 分治本质上就是把原问题分解为几个子问题来解决。
// 快速排序也是分治思想来解决。
//
//
// 归并排序(merge-sort):
// 1. 把一个待排序的数组分解为两个子数组;
// 2. 对两个子数组进行排序(通过递归地调用自己来实现);
// 3. 对两个已经排序的数组进行合并。
//
// 分析:
// 1. 一个数组一直分解下去,只到分解成只包含一个元素的子数组为止, 此时自然是有序的;
// 2. 归并排序的重点在于合并,而不是对子数组的排序。(快速排序与它恰恰相反,快速排序的
// 重点是对子数组进行排序,而不是合并,因为它不需要合并了)
//
//
#include <cstring>
#include <iostream>
typedef bool(*CompareFunc)(int, int); // 下面函数实现合并功能,输入三个下标参数表示了两个子数组, :[nStart_, nMiddle)和[nMiddle, nEnd)
void Merge(int array[], int nStart_, int nMiddle_, int nEnd_, CompareFunc comp)
{
if (array == nullptr || nStart_ >= nMiddle_ || nMiddle_ >= nEnd_)
return; // 建立一个临时数组存放中间数据
int _nIndex = ;
int* _pTempArray = new int[nEnd_ - nStart_]; // 对两个子数组进行合并
int _nStartChange = nStart_;
int _nMiddleChange = nMiddle_;
while (_nStartChange < nMiddle_ && _nMiddleChange < nEnd_)
{
// 此处的if中比较语句的安排可以保持稳定排序的特性。
if (comp(array[_nMiddleChange], array[_nStartChange]))
{
_pTempArray[_nIndex] = array[_nMiddleChange];
++_nMiddleChange;
}
else
{
_pTempArray[_nIndex] = array[_nStartChange];
++_nStartChange;
}
++_nIndex;
} // 把不为空的子数组的元素追加到临时数
if (_nStartChange < nMiddle_)
{
memcpy(_pTempArray + _nIndex, array + _nStartChange, sizeof(int) * (nMiddle_ - _nStartChange));
}
else if (_nMiddleChange < nEnd_)
{
memcpy(_pTempArray + _nIndex, array + _nMiddleChange, sizeof(int) * (nEnd_ - _nMiddleChange));
}
else
{
/* do noting */
} // 数据交换
memcpy(array + nStart_, _pTempArray, sizeof(int) * (nEnd_ - nStart_)); delete [] _pTempArray;
_pTempArray = nullptr;
} // 归并排序功能实现函数
void MergeSort(int array[], int nStart_, int nEnd_, CompareFunc comp)
{
// 数组指针为空,或者数组内的个数少于等于1个时,直接返回。
if (nullptr == array || (nEnd_ - nStart_) <= )
return; // 划分为两个子数组并递归调用自身进行排序
int _nMiddle = (nStart_ + nEnd_) / ;
MergeSort(array, nStart_, _nMiddle, comp);
MergeSort(array, _nMiddle, nEnd_, comp); // 合并排序完成的子数组
Merge(array, nStart_, _nMiddle, nEnd_, comp);
} // 比较函数
bool less(int lhs, int rhs)
{
return lhs < rhs;
} // 打印数组函数
void PrintArray(int array[], int nLength_)
{
if (nullptr == array || nLength_ <= )
return; for (int i = ; i < nLength_; ++i)
{
std::cout << array[i] << " ";
} std::cout << std::endl;
} /*************** main.c *********************/
>>int main(int argc, char* argv[])
{
// 测试1
int array[] = {, -, , , -, -, -, , -, -};
PrintArray(array, );
MergeSort(array, , , less);
PrintArray(array, ); // 测试2
int array2[] = {};
PrintArray(array2, );
MergeSort(array2, , , less);
PrintArray(array2, ); // 测试3
int array3[] = {, -};
PrintArray(array3, );
MergeSort(array3, , , less);
PrintArray(array3, ); return ;
}

排序算法的c++实现——归并排序的更多相关文章

  1. Python排序算法(六)——归并排序(MERGE-SORT)

    有趣的事,Python永远不会缺席! 如需转发,请注明出处:小婷儿的python https://www.cnblogs.com/xxtalhr/p/10800699.html 一.归并排序(MERG ...

  2. 【高级排序算法】2、归并排序法的实现-Merge Sort

    简单记录 - bobo老师的玩转算法系列–玩转算法 -高级排序算法 Merge Sort 归并排序 Java实现归并排序 SortTestHelper 排序测试辅助类 package algo; im ...

  3. 【高级排序算法】1、归并排序法 - Merge Sort

    归并排序法 - Merge Sort 文章目录 归并排序法 - Merge Sort nlogn 比 n^2 快多少? 归并排序设计思想 时间.空间复杂度 归并排序图解 归并排序描述 归并排序小结 参 ...

  4. 四、排序算法总结二(归并排序)(C++版本)

    一.什么是归并排序? 归并排序是基于分而治之的思想建立起来的. 所谓的分而治之,也就是将一个数据规模为N的数据集,分解为两个规模大小差不多的数据集(n/2),然而分别处理这两个更小的问题,就相当于解决 ...

  5. 排序算法Java实现(归并排序)

    算法描述:对于给定的一组记录,首先将每两个相邻的长度为1的子序列进行归并,得到 n/2(向上取整)个长度为2或1的有序子序列,再将其两两归并,反复执行此过程,直到得到一个有序序列. package s ...

  6. 排序算法Nb三人组-归并排序

    归并排序只能对两个已经有序的列表进行合并排序,所以要我们自己创建出两个有序列表.最后在进行合并. def merge2list(li1, li2): li = [] i = 0 j = 0 while ...

  7. 简易版的TimSort排序算法

    欢迎探讨,如有错误敬请指正 如需转载,请注明出处http://www.cnblogs.com/nullzx/ 1. 简易版本TimSort排序算法原理与实现 TimSort排序算法是Python和Ja ...

  8. [Data Structure & Algorithm] 八大排序算法

    排序有内部排序和外部排序之分,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.我们这里说的八大排序算法均为内部排序. 下图为排序 ...

  9. JS家的排序算法

    由于浏览器的原生支持(无需安装任何插件),用JS来学习数据结构和算法也许比c更加便捷些.因为只需一个浏览器就能啪啪啪的调试了.比如下图我学习归并排序算法时,只看代码感觉怎么都理解不了,但是结合chro ...

随机推荐

  1. 机器学习-MNIST数据集-神经网络

    #设置随机种子 seed = 7 numpy.random.seed(seed) #加载数据 (X_train,y_train),(X_test,y_test) = mnist.load_data() ...

  2. LeetCode 1146. Snapshot Array

    原题链接在这里:https://leetcode.com/problems/snapshot-array/ 题目: Implement a SnapshotArray that supports th ...

  3. 从三数之和看如何优化算法,递推-->递推加二分查找-->递推加滑尺

    人类发明了轮子,提高了力的使用效率. 人类发明了自动化机械,将自己从重复的工作中解脱出来. 提高效率的方法好像总是离不开两点:拒绝无效劳动,拒绝重复劳动.人类如此,计算机亦如是. 前面我们说过了四数之 ...

  4. springmvc,controller层在接收浏览器url传来的参数带中文乱码问题。

    请求地址:http://localhost:8080/saveFlashSale?fsRemark=哈哈哈哈哈 接收方法:@RequestMapping("/saveFlashSale&qu ...

  5. Docker环境下的前后端分离项目部署与运维(八)使用Docker部署RabbitMQ集群

    下载RabbitMQ镜像 镜像地址RabbitMQ Docker官方认证镜像地址:https://hub.docker.com/_/rabbitmq 安装命令安装之前,切记把Docker Hub设置为 ...

  6. 详解手把手Maven搭建SpringMVC+Spring+MyBatis框架(超级详细版)

    转载(https://www.jb51.net/article/130560.htm) SSM(Spring+SpringMVC+Mybatis),目前较为主流的企业级架构方案.标准的MVC设计模式, ...

  7. ESRally压测ElasticSearch性能 CentOS 7.5 安装 Python3.7

    1,CentOS 7.5 安装 Python3.7 1.安装开发者工具 yum -y groupinstall "Development Tools"2.安装Python编译依赖包 ...

  8. @RequestMapping 用法详解

    简介: @RequestMapping RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上.用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径. RequestM ...

  9. 2 Linux性能优化--工具图

  10. Mysql变量、存储过程、函数、流程控制

    一.系统变量 系统变量: 全局变量 会话变量 自定义变量: 用户变量 局部变量 说明:变量由系统定义,不是用户定义,属于服务器层面 注意:全局变量需要添加global关键字,会话变量需要添加sessi ...