合并排序
分治算法:
用分治策略实现n个元素进行排序的方法。
基本思想:
将待排序元素分成大小大致相同的两个子集合,分别对两个子集合进行排序,最终排好序的子集合合并成所要求的排好序的集合。
源码:
/* * mergeSort.cpp * 合并排序算法,算法导论P.17 * Created on: 2011-12-21 * Author: LiChanghai */ //#include <iostream> #include <vector> #include <iostream> #include <iterator> using namespace std; #define FLT_MAX 1.0E38 //定义一个很大的值作为哨兵 //对于待排序的数组 A[p...r], 其子数组A[p...q],A[q+1...r]已排好序 //函数 subMerge(A, p, q, r), 将两个已排好序的子数组A[p...q],A[q+1...r] //合并成一个有序的数组代替当前的数组A[p...r] template<typename T> void subMerge(vector<T> &array, typename vector<T>::iterator iterBegin, typename vector<T>::iterator iterBarrier, typename vector<T>::iterator iterEnd) { //创建两个数组,分别存放以iterBarrier为界线的array的左边部分和右边部分 vector<T> arrayLeft(iterBegin, iterBarrier+1); vector<T> arrayRight(iterBarrier+1, iterEnd); //在两个数组尾部分别放一个“哨兵” T temp = T(FLT_MAX); arrayLeft.push_back(temp); arrayRight.push_back(temp); //定义分别指向两个数组的迭代器 typename vector<T>::iterator iterLeft = arrayLeft.begin(); typename vector<T>::iterator iterRight = arrayRight.begin(); //定义指向原数组array的迭代器 typename vector<T>::iterator iterArray = iterBegin; for(; iterArray != iterEnd; ++iterArray) if(*iterLeft < *iterRight) //如果左边小,将左边的值放入原数组 { *iterArray = *iterLeft; ++iterLeft; } else //如果右边小,将右边的值放入原数组 { *iterArray = *iterRight; ++iterRight; } return; } //函数 mergeSort(A, p, r) 调用subMerge对任意数组排序,p, r为下标 //mergeSort(A, p, r)首先将数组A分为两部分 //然后递归调用其本身对这两部分 分别排序 //依次递归下去,直到只剩2个数的时候完成这两个数的排序 //然后再层层返回调用处,将已排好序的子序列合并成更大的有序序列 //最后一次调用subMerge时完成数组的排序 template<typename T> void mergeSort(vector<T> &vec, typename vector<T>::iterator iterHead, typename vector<T>::iterator iterTail) { //测试 mergeSort 调用了多少次 //static int times_mergeSort=0; //cout<<"the "<<++times_mergeSort<<" call mergeSort()"<<endl; //测试 subMerge 调用了多少次 //static int times_subMerge=0; if(iterHead < iterTail-1) { //数组长度的一半(错误的方法) //typename vector<T>::size_type halfLength = (vec.size()-1)/2; //数组长度的一半(正确方法) typename vector<T>::difference_type halfLength=( (iterTail-iterHead)-1)/2; //定义一个迭代器指向数组 vec 中间位置 typename vector<T>::iterator iterDivide = iterHead + halfLength; mergeSort(vec, iterHead, iterDivide+1); //递归调用自身对前半段排序 mergeSort(vec, iterDivide+1, iterTail); //递归调用自身对后半段排序 //cout<<"the "<<++times_subMerge<<" call subMerge()"<<endl; subMerge(vec, iterHead, iterDivide, iterTail); //将上面排好序的两段合并 } return; } int main() { vector<int> vec; vec.push_back(0); vec.push_back(9); vec.push_back(8); vec.push_back(7); vec.push_back(6); vec.push_back(5); vec.push_back(4); vec.push_back(3); vec.push_back(2); vec.push_back(1); int size = vec.size(); int *phead = &vec[0]; int *ptail = &vec[size]; mergeSort(vec,phead,ptail); for(int i=0;i<10;i++) cout<<vec[i]<<" "; cout<<endl; return 0; }
运行结果:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?