归并排序
来源:互联网 发布:linux vi 全选复制 编辑:程序博客网 时间:2024/06/11 02:09
概述
归并排序是典型的分而治之策略的应用。主要是把一个数组分成若干个子数组进行从小到大的归并直至有序。下面所说的归并排序默认为2路归并排序。
递归算法思想
1)将数组平分为2等份,对这两个子数组进行从小大到有序归并。
2)递归对左半部分进行2路归并
3)递归对右半部分进行2路归并
//一趟归并 void Merge(int* data,int* tmp,int left,int right,int rightend){ int leftend = right-1; int size = rightend-left+1; int cnt = left; while(left <= leftend && right <= rightend){ if(data[left] < data[right]){ tmp[cnt++] = data[left++]; }else{ tmp[cnt++] = data[right++]; } } while(left <= leftend){ tmp[cnt++] = data[left++]; } while(right <= rightend){ tmp[cnt++] = data[right++]; } for(int i = 0 ; i < size ; i++,rightend--){ data[rightend] = tmp[rightend]; }}//归并排序 void Msort(int* data,int* tmp,int left,int rightend){ if(left < rightend){ int mid = (left+rightend)/2; Msort(data,tmp,left,mid); Msort(data,tmp,mid+1,rightend); Merge(data,tmp,left,mid+1,rightend); }}//归并排序(递归版本)void Merge_Sort(int* data,int size){ int* tmp = new int[size]; if(tmp != NULL){ Msort(data,tmp,0,size-1); }}
非递归算法思想
1)首先构造一个与原数组大小一样的临时数组
2)设置归并长度length = 1,从头开始堆两个length长度的数组进行归并到tmp直至倒数第二组。由于原数组长度与length布置时候能整除,如果能整除,那么把最后一组归并到数组了,若不能,那么就直接导入tmp数组。
3)更新length,使之翻倍,重复上述2)操作,只不过是把tmp的数组归并到原数组。
4)重复上述2)与3)操作,直至length大于数组长度。
//一趟归并 void Merge(int* data,int* tmp,int left,int right,int rightend){ int leftend = right-1; int size = rightend-left+1; int cnt = left; while(left <= leftend && right <= rightend){ if(data[left] < data[right]){ tmp[cnt++] = data[left++]; }else{ tmp[cnt++] = data[right++]; } } while(left <= leftend){ tmp[cnt++] = data[left++]; } while(right <= rightend){ tmp[cnt++] = data[right++]; } for(int i = 0 ; i < size ; i++,rightend--){ data[rightend] = tmp[rightend]; }}//一趟归并排序void Merge_Pass(int* data,int* tmp,int size,int length){ int i; for(i = 0 ; i <= size-2*length ; i += 2*length){ Merge(data,tmp,i,i+length,i+2*length-1); } if(i+length < size){//归并最后两个子序列 Merge(data,tmp,i,i+length,size-1); }else{//归并最后一个子序列 for(int j = i ; j < size ; j++){ tmp[j] = data[j]; } }}//归并排序(非递归排序)void Merge_Sort1(int* data,int size){ int* tmp = new int[size]; int length = 1; if(tmp != NULL){ while(length < size){ Merge_Pass(data,tmp,size,length); length*=2; Merge_Pass(tmp,data,size,length); length*=2; } delete tmp; }}
全部代码
#include <iostream>#include <cstdlib>#include <ctime>using namespace std;//初始化数组 void SetArray(int* data,int size){ //srand(time(0)); cout<<"随机初始化"<<size<<"个数"<<endl; for(int i = 0 ; i < size ; i++){ data[i] =rand()%100+1; }}//打印函数 void Print(int* data ,int size){ for(int i = 0 ; i < size ; i++){ cout<<data[i]<<" "; } cout<<endl;} //一趟归并 void Merge(int* data,int* tmp,int left,int right,int rightend){ int leftend = right-1; int size = rightend-left+1; int cnt = left; while(left <= leftend && right <= rightend){ if(data[left] < data[right]){ tmp[cnt++] = data[left++]; }else{ tmp[cnt++] = data[right++]; } } while(left <= leftend){ tmp[cnt++] = data[left++]; } while(right <= rightend){ tmp[cnt++] = data[right++]; } for(int i = 0 ; i < size ; i++,rightend--){ data[rightend] = tmp[rightend]; }}//归并排序 void Msort(int* data,int* tmp,int left,int rightend){ if(left < rightend){ int mid = (left+rightend)/2; Msort(data,tmp,left,mid);//递归归并排序左半部分 Msort(data,tmp,mid+1,rightend);//递归归并排序右半部分 Merge(data,tmp,left,mid+1,rightend);//对左右部分进行有序归并 }}//归并排序(递归版本)void Merge_Sort(int* data,int size){ int* tmp = new int[size]; if(tmp != NULL){ Msort(data,tmp,0,size-1); }}//一趟归并排序void Merge_Pass(int* data,int* tmp,int size,int length){ int i; for(i = 0 ; i <= size-2*length ; i += 2*length){ Merge(data,tmp,i,i+length,i+2*length-1); } if(i+length < size){//归并最后两个子序列 Merge(data,tmp,i,i+length,size-1); }else{//归并最后一个子序列 for(int j = i ; j < size ; j++){ tmp[j] = data[j]; } }}//归并排序(非递归排序)void Merge_Sort1(int* data,int size){ int* tmp = new int[size]; int length = 1; if(tmp != NULL){ while(length < size){ Merge_Pass(data,tmp,size,length); length*=2; Merge_Pass(tmp,data,size,length); length*=2; } delete tmp; }}int main(){ cout<<"请输入数组长度:"<<endl; int size,*data; cin>>size; data = new int[size]; SetArray(data,size); cout<<"归并排序(递归版本)前:"<<endl; Print(data,size); cout<<"归并排序(递归版本)后:"<<endl; Merge_Sort(data,size); Print(data,size); SetArray(data,size); cout<<"归并排序(非递归版本)前:"<<endl; Print(data,size); cout<<"归并排序(非递归版本)后:"<<endl; Merge_Sort1(data,size); Print(data,size); return 0; }
截图:
阅读全文
0 0
- 归并排序-归并排序
- 归并和归并排序
- 归并与归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 排序::归并
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- sqlite3问题笔记
- 快速排序优化-尾递归(需再加内容)
- 教大家一种迅雷下载百度云文件方法
- 可行性研究
- 美联储启动缩表 | 昨晚,一个时代正式宣告结束
- 归并排序
- SS加密方式浅析
- JavaScript进阶之事件
- Spring框架简介
- 2017年9月24日训练总结
- Java中StringBuffer方法
- ServletContext及其相关方法
- caioj1064 最长上升子序列
- Python3:urllib中urlopen()函数新特点