归并排序(递归实现)

要求:

用递归实现,每次的合并操作结束后,输出当前的排序结果。

输入:

第一行,一个数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 }
posted @ 2019-12-18 13:18  Cyber_8086_hyj  阅读(483)  评论(0编辑  收藏  举报