排序算法的c++实现——归并排序
归并排序是典型分治思想的代表——首先把原问题分解为两个或多个子问题,然后求解子问题的解,最后使用子问题的解来构造出原问题的解。
对于归并排序,给定一个待排序的数组,首先把该数组划分为两个子数组,然后对子数组进行排序(递归调用归并排序),最后对两个有序的子数组进行合并,使合并之后的数组为有序状态。
让我们想想,把一个数组不断地划分为子数组,不断地划分......,不断地划分......., 最后停止了划分不下去了。 此时子数组的元素有一个,它们本身就是有序的。接下来,我们就需要执行合并过程,不断地一层层向上合并,........, 直到原数组。通过这个过程就会发现, 归并排序的核心在于合并有序的子数组,而不是对子数组进行排序,因为最底层的子数组本身就是有序的,上一层子数组如果想要变成有序的,通过合并底层有序的子数组就可以得到, 最终我们使原数组变成了有序的,从而完成了排序操作。
说明几点:
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++实现——归并排序的更多相关文章
- Python排序算法(六)——归并排序(MERGE-SORT)
有趣的事,Python永远不会缺席! 如需转发,请注明出处:小婷儿的python https://www.cnblogs.com/xxtalhr/p/10800699.html 一.归并排序(MERG ...
- 【高级排序算法】2、归并排序法的实现-Merge Sort
简单记录 - bobo老师的玩转算法系列–玩转算法 -高级排序算法 Merge Sort 归并排序 Java实现归并排序 SortTestHelper 排序测试辅助类 package algo; im ...
- 【高级排序算法】1、归并排序法 - Merge Sort
归并排序法 - Merge Sort 文章目录 归并排序法 - Merge Sort nlogn 比 n^2 快多少? 归并排序设计思想 时间.空间复杂度 归并排序图解 归并排序描述 归并排序小结 参 ...
- 四、排序算法总结二(归并排序)(C++版本)
一.什么是归并排序? 归并排序是基于分而治之的思想建立起来的. 所谓的分而治之,也就是将一个数据规模为N的数据集,分解为两个规模大小差不多的数据集(n/2),然而分别处理这两个更小的问题,就相当于解决 ...
- 排序算法Java实现(归并排序)
算法描述:对于给定的一组记录,首先将每两个相邻的长度为1的子序列进行归并,得到 n/2(向上取整)个长度为2或1的有序子序列,再将其两两归并,反复执行此过程,直到得到一个有序序列. package s ...
- 排序算法Nb三人组-归并排序
归并排序只能对两个已经有序的列表进行合并排序,所以要我们自己创建出两个有序列表.最后在进行合并. def merge2list(li1, li2): li = [] i = 0 j = 0 while ...
- 简易版的TimSort排序算法
欢迎探讨,如有错误敬请指正 如需转载,请注明出处http://www.cnblogs.com/nullzx/ 1. 简易版本TimSort排序算法原理与实现 TimSort排序算法是Python和Ja ...
- [Data Structure & Algorithm] 八大排序算法
排序有内部排序和外部排序之分,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.我们这里说的八大排序算法均为内部排序. 下图为排序 ...
- JS家的排序算法
由于浏览器的原生支持(无需安装任何插件),用JS来学习数据结构和算法也许比c更加便捷些.因为只需一个浏览器就能啪啪啪的调试了.比如下图我学习归并排序算法时,只看代码感觉怎么都理解不了,但是结合chro ...
随机推荐
- Huffman树与Huffman编码
1.Huffman树 今天复习Huffman树.依稀记得自己被Huffman树虐的经历.还记得是7月份,我刚开始看数据结构与算法,根本看不懂Huffman树的操作.后来我终于悟出了Huffman树是怎 ...
- nodejs内存溢出 FATAL ERROR: CALL_AND_RETRY_0 Allocation failed – process out of memory
spa项目整体迁移转为ssr后,改动之后部署一切还好,就是突然有一天访问人数太多,node进程很容易就挂了自动重启. 最后经过压力测试,考虑到是堆内存溢出的问题,就报错误:FATAL ERROR: C ...
- kubernetes node节点失效 调度
kubernetes 配置: 测试node挂 机,发布需要等几分才会 在其它 的node机器 启动,这个明显不合理,对于大多数业务 kube-controller-manager配置: /etc/sy ...
- Idea 进行断点调试的 快捷键
快捷键 功能描述F8 单步调试,不进入函数内部F7 单步调试,进入函数内部Shift+F7 选择要进入的函数Shift+F8 跳出函数Alt+F9 运行到断点Alt+F8 执行表达式查看结果F9 继续 ...
- .NET 微服务 学习目录
概述 微服务在Java端已经有很成熟的框架可以使用,之前.NET一直没有比较成熟的网关,最近发现 Ocelot 这个.NET开源的微服务网关功能越来越强大,正好照着微软的官方文档学些一下.NET的微服 ...
- cad.net 块裁剪边界反向修剪
Querying for XCLIP information inside AutoCAD using .NET 这里下面观众讨论了 How do I determine if an x-clip ...
- Spring的NamedParameterJdbcTemplate的简单使用
原文地址:https://www.iteye.com/blog/itommy-2354746 Spring JDBC包提供了JdbcTemplate和它的两个兄弟SimpleJdbcTemplate和 ...
- Linux shell脚本单例模式实现
一.说明 关于单例模式,最开始的是一些小工具,运行起来后再点击运行时会提示已经运行了一个实例,觉得挺有意思但也没有很在意. 前段时间看了前领导的一段代码不太懂是做什么用的,同事查了下资料说是为了实现单 ...
- spring cloud 服务治理 - Eureka
前言 在分布式系统领域有个著名的CAP定理: C——数据一致性: A——服务可用性: P——服务对网络分区故障的容错性. 这三个特性在任何分布式系统中不能同时满足,最多同时满足两个. Zookeepe ...
- Mysql 学习参考
[1]Mysql 基础知识 (1)<Mysql 官网> (2)<菜鸟教程之Mysql数据库教程> (3)<C语言中文网之Mysql数据库栏> (4)<W3Sc ...