归并排序的递归以及迭代两种实现和优化
来源:互联网 发布:sofifa数据库手机版 编辑:程序博客网 时间:2024/06/16 22:48
本文主要探讨归并排序的递归以及迭代两种实现和优化
归并排序MergeSort
是一种经典而高效的排序算法,是一种采用分而治之(devide and conquer)方法的一个典型应用。
假使要得到一个有序完全有序序列,可以使构成其的两个子序列有序,然后在将它们合并;若使子序列有序,则应使子序列间断有序。这样的方法叫做二路归并。
具体的算法思想和复杂度可以参考:这一篇
本文着重介绍归并排序的两种实现,一种是递归实现,另外一种是迭代实现。
首先介绍其递归实现,有一点值得留心,就是对于排序区间是开区间还是闭区间:
template <typename T> void merge(T arr[], int lo, int mi, int hi){// cout<<"merging ["<<lo<<","<<mi<<"] + ["<<"["<<mi+1<<","<<hi<<"]"<<endl; //合并的过程,开辟额外的存储空间 //[lo,mi), [mi,hi) 合并// T C[lc];// for (int i = 0; i <lc ; ++i) {// C[i]=arr[mi+1+i];// }// T* A=arr+lo;// int lb=mi-lo;// T* B=new T[lb];// for (int i = 0; i < lb; B[i]=A[i++]);//前半段子向量//// int lc=hi-mi;//向量的后半段// T* C=arr+mi;// for (int i=0, j=0, k=0; (j<lb)||(k<lc); ){// //cout<<"i="<<i<<"j="<<j<<" k="<<k<<endl;// if ( ( j < lb ) && ( ! ( k < lc ) || ( B[j] <= C[k] ) ))// A[i++]=B[j++];//前半段比较小// if ( (k<lc) &&( !( j<lb )|| ( C[k]<B[j] )))// A[i++]=C[k++];//后半段比较小// }//// delete[] B; //闭区间 T* A=arr+lo; int lb=mi-lo+1;//+1 T* B=new T[lb]; for (int i = 0; i < lb; B[i]=A[i++]);//前半段子向量 int lc=hi-mi;//向量的后半段 [mi+1, hi] T* C=arr+mi+1;//+1 for (int i=0, j=0, k=0; (j<lb)||(k<lc); ){ //cout<<"i="<<i<<"j="<<j<<" k="<<k<<endl; if ( ( j < lb ) && ( ! ( k < lc ) || ( B[j] <= C[k] ) )) A[i++]=B[j++];//前半段比较小 if ( (k<lc) &&( !( j<lb )|| ( C[k]<B[j] ))) A[i++]=C[k++];//后半段比较小 } delete[] B; } template <typename T> void __mergeSort(T arr[], int lo, int hi){//[lo,hi]排序 //assert(lo<=hi);// if (hi-lo<2)//开区间// return; if (lo>=hi)//闭区间 return;// {cout<<"rerurn"<<endl; return;} int mi=(lo+hi)/2;// cout<<"l sorting ["<<lo<<" , "<<mi<<"]"<<endl; __mergeSort(arr, lo, mi);// cout<<"1. finish ["<<lo<<" , "<<mi<<"]"<<endl; // cout<<"lo1="<<lo<<" mi1="<<mi<<endl; // __mergeSort(arr, mi, hi);// cout<<"r sorting ["<<mi+1<<" , "<<hi<<"]"<<endl; __mergeSort(arr, mi+1, hi);//闭区间// cout<<"2. finish ["<<mi+1<<" , "<<hi<<"]"<<endl; // cout<<"mi+1="<<mi+1<<" hi="<<hi<<endl; if (arr[mi] > arr[mi+1])//这一步优化,只有当前后无序才进行合并 merge(arr, lo, mi, hi);// cout<<"merge finished"<<endl; } // 归并排序 // 时间复杂度O(nlogn) template <typename T> void mergeSort(T arr[], int n){ // __mergeSort(arr, 0, n);//[0,n)开区间 __mergeSort(arr, 0, n-1);//[0,n-1]闭区间 }
另外一种为非递归实现
//时间复杂度O(NLOGN)//空间复杂度O()//对于arr[lo,hi)进行排序//template <typename T>//void mergeSort(T arr[], int lo, int hi){// //非递归实现//}template <typename T>void __merge(T arr[], int l, int mi, int r, T aux[]){ //合并arr[l,mi] [mi+1, hi] for (int i=l; i<=r; i++) aux[i]=arr[i]; int i=l,j=mi+1;//i 表示前半段,j表示后半段 for (int k=l; k<=r;k++){//k表示需要进行覆盖的整个串 if (i>mi){//表示前半段已经赋值完了 arr[k]=aux[j];j++; } else if(j>r){//表示后半段赋值完了 arr[k]=aux[i];i++; } else if (aux[i]<aux[j]){//谁小谁赋值 arr[k]=aux[i];i++; } else { arr[k]=aux[j];j++; } }}//对于arr[0.n)进行归并排序void mergeSort(int arr[], int n){ //非递归实现 assert(n>0); int* aux=new int[n]; for (int i=0;i<n;++i){ aux[i]=arr[i]; } for (int sz=1; sz<n;sz+=sz){ for (int i=0; i<n ;i+=sz+sz){ //arr[i, i+sz) [i+sz, i+sz+sz) 合并 __merge( arr, i, i+sz-1, min(n-1,i+sz+sz-1), aux); } } delete[] aux; return ;}
未完……
阅读全文
0 0
- 归并排序的递归以及迭代两种实现和优化
- 归并排序以及归并排序的优化
- 三大面试排序的归并以及递归实现--快速排序、归并排序、堆排序
- Java实现的归并排序算法(递归优化版)
- 归并排序的递归和非递归实现方法
- 归并排序的递归和非递归实现
- 归并排序的递归实现
- 递归实现的归并排序
- 归并排序的递归实现
- 归并排序 递归和非递归实现
- 归并排序递归和非递归实现
- 归并排序非递归和递归实现
- 递归和非递归实现归并排序
- 递归和迭代两种方式实现归并排序(Java版)
- 归并排序递归实现
- 归并排序-递归实现
- 归并排序递归实现
- 归并排序(递归实现)
- Java8 04 新日期时间API
- 项目中遇到的坑--数据库自动释放连接
- py4j.protocol.Py4JJavaError错误
- 在使用ifconfig命令时出现了无法安装的问题,解决方法
- 朋友勇和他们分公司的致远OA A8v5 6.1的授权注册
- 归并排序的递归以及迭代两种实现和优化
- hibernate进阶(二)
- RPM文件安装时最后加上 --nodeps --force参数是什么意思
- php中引用&的真正理解-变量引用、函数引用、对象引用
- Celery(1):celery简介及安装
- Maven学习笔记(二)
- C/C++学习框架参考
- 关于廖雪峰yield,协程,异步的一些学习记录
- xilinx SDK使用教程