数据结构之归并排序

来源:互联网 发布:围巾 男 知乎 编辑:程序博客网 时间:2024/05/17 02:49
//编写一个归并排序程序,并在main函数中验证结果/**归并排序(Merging Sort)是利用“归并”技术进行排序,所谓归并*是指将若干个已排序好的子表合并成一个有序表*最简单的归并是将两个有序的子表合并成一个有序表。假设R[low]*到R[mid]和R[mid+1]到R[high]是存储在同一个数组中且相邻的两个有序表*要将它们合并为一个有序表R1[low]到R1[high],只要设置3个指示器i,j和k,*其初值分别是这3个记录区的起始位置。合并时依次比较R[i]和R[j]的关键字,*取关键字较小的记录复制到R1[k]中,然后,将指向复制记录的指示器加1和*指向复制位置的指示器加1,重复这一过程,直到全部记录都复制如R1[low]*到R1[high]中为止。*下面给出二路归并排序的全过程:*初始关键字:  49 38 65 97 76 13 49'*初始子表:    [49][38] [65] [97] [76] [13] [49']*第一趟归并后:[38 49][65 97] [13 76] [49']*第二趟归并后:[38 49 65 97] [13 49' 76]*第三趟归并后:[13 38 49 49' 65 76 97]*///代码清单如下:#include<iostream>using namespace std;const int maxsize=100;//排序表容量,假设为100typedef int datatype;typedef struct{datatype key;//关键字域}rectype;//记录表类型typedefrectype list[maxsize];//排序表类型,0号单元不用//两个有序表合并成一个有序序列void Merge(list R,list R1,int low,int mid,int high){//合并R的两个子表,结果在R1中int i,j,k;i=low;j=mid+1;k=low;while(i<=mid && j<=high)if(R[i].key<=R[j].key){R1[k]=R[i];//取小者复制到R1中k++; i++;}//记录后移else{R1[k]=R[j];k++;j++;}while(i<=mid) R1[k++]=R[i++];//若左子表合并完,复制剩余记录while(j<=high) R1[k++]=R[j++];//若右子表合并完,复制剩余记录}//一趟归并问题void Mergepass(list R,list R1,int n,int len){//对R做一趟合并,结果在R1中int i,j;i=1;//i指向第一对子表的起始点while(i+2*len-1<=n){//归并长度为len的两个子表Merge(R,R1,i,i+len-1,i+2*len-1);i=i+2*len;//i指向下一对子表起始点}if(i+len-1<n)//剩下两个子表Merge(R,R1,i,i+len-1,n);elsefor(j=i;j<=n;j++)//将最后一个表复制到R1中R1[j]=R[j];for(i=1;i<=n;i++)cout<<R[i].key<<" ";cout<<endl;}//二路归并算法void Mergesort(list R,list R1,int n){//对R二路归并排序,结果在R中(非递归算法)int len,k;len=1;//开始时,len为1k=1;while(len<n){Mergepass(R,R1,n,len);//一趟归并,结果在R1中cout<<"第"<<k++<<"趟归并后:"<<endl;len=len*2;Mergepass(R1,R,n,len); len=len*2;//再次归并,结果在R中}}//main函数验证结果int main(){list R,R1;const int n=8;cout<<"   欢迎来到wwj的C++学习乐园!!!!  "<<endl;cout<<"请输入你要进行归并排序的无序表:"<<endl;for(int i=1;i<=n;i++)cin>>R[i].key ;cout<<endl;cout<<"无序表如下:"<<endl;for(int i=1;i<=n;i++)cout<<R[i].key<<" ";cout<<endl;cout<<"二路归并排序全过程如下:"<<endl;Mergesort(R,R1,n);cout<<"最后排序结果为:"<<endl;for(int i=1;i<=n;i++)cout<<R[i].key<<" ";system("pause");return 0;}