归并排序(递归实现)
要求:
用递归实现,每次的合并操作结束后,输出当前的排序结果。
输入:
第一行,一个数n,表示n个数需要排序。
第二行,输入这n个需要排序的数字。
(注意,当n为奇数时,划分为两部分,前半部分为n/2+1,后半部分为n/2)
标准输入:
9
9 8 7 6 5 4 3 2 1
标准输出:
8 9 7 6 5 4 3 2 1
7 8 9 6 5 4 3 2 1
7 8 9 5 6 4 3 2 1
5 6 7 8 9 4 3 2 1
5 6 7 8 9 3 4 2 1
5 6 7 8 9 3 4 1 2
5 6 7 8 9 1 2 3 4
1 2 3 4 5 6 7 8 9
思路:(1)先将数组划分为一个个块,直到不能再划分为止(分)
(2)对划分的数组进行排序
需要:(1)一个临时变量数组p,存储每次归并后的值,然后赋给a(这个时候p处理归并数据下标的范围和a的下标范围一致)
(2)一个函数,用来分(划分下标范围)
(3)一个函数,用来治(将两组数据归并,归并后即为排序)
详细请见代码及注释
1 #include<bits/stdc++.h> 2 using namespace std; 3 void Mergesort(int a[],int begin,int mid,int end,int n,int p[]) //归并排序 4 { 5 int i=begin,j=mid+1,k=i; 6 //i是左分组起始下标,mid是分组边界也是i的上界,j是右分组的左边界,j上界为end,k为临时储存数组p的下标 7 while (i<=mid&&j<=end) //开始对两个分组进行归并 8 { 9 if (a[i]<a[j]) p[k++]=a[i++]; //分组中小的放先放进p,然后递增下标 10 else p[k++]=a[j++]; 11 } //循环结束时,左右两分组必有一个没有全部并到临时储存数组p 12 while(i<=mid) p[k++]=a[i++]; //这时我们需要检查,并把没有并的放到p里面 13 while(j<=end) p[k++]=a[j++]; 14 for (int i = 0; i < (end-begin+1); i++) a[i+begin]=p[i+begin]; //把归并好的放到a里 15 for(int i=0;i<n;i++) cout<<a[i]<<" "; //输出每一步的归并结果 16 cout<<endl; 17 } 18 19 void Divide_Conquer(int a[],int begin,int end,int n,int p[]) //递归分治 20 { 21 if (begin<end) 22 { 23 int mid=begin+(end-begin)/2; //定一个分治的边界 24 Divide_Conquer(a,begin,mid,n,p); //左分 25 Divide_Conquer(a,mid+1,end,n,p); //右分 26 Mergesort(a,begin,mid,end,n,p); //治,对分的数据进行排序 27 } 28 29 } 30 31 int main() 32 { 33 int n; 34 cin>>n; //输入数组大小 35 int a[n],p[n]; //a[n]为数组,p[n]为临时数组 36 for(int i=0;i<n;i++) cin>>a[i]; //输入数组数值 37 Divide_Conquer(a,0,n-1,n,p); //开始分治,归并 38 //cout<<"Array after sort:"<<endl; 39 //for(int i=0;i<n;i++) cout<<a[i]<<" "; //输出归并的值 40 //cout<<endl; 41 return 0; 42 }