归并排序

归并排序主要分为三步:

        划分问题:  把序列分为元素个数尽量相等的两半;

        递归求解: 把两半元素分别进行排序

        合并问题: 把两个有序表合并成一个;

  其中前两部分比较容易,关键是第三部分合并数组;

 

归并函数 1 void mergerSort(int arr[], int start, int end, int T[]); 

        参数说明: 

     arr[] : 待排序的数组
     start : 子空间排序的开始下标(最开始从0开始)
     end : 子空间排序的结束下标(最开始从n-1开始)
     T[] : 合并数组前的保存数据的临时数组(数组大小与arr相同)

划分问题:

        当数组长度大于或等于2时,对数组进行划分: 前半部分从start开始,mid结束;后半部分从mid+1开始,end结束;

1         if(end-start>0){                 
2            int i = start;               // 临时数组的开始下标  
3           int mid = (end+start)/2;     // 划分子空间的中点 
4           int p=start, q=mid+1;        // 两个子空间的开始下标
5         }

递归求解:

  分两个子序列进行排序;

1         // 子空间递归求解 
2         mergerSort(arr, start, mid , T);
3         mergerSort(arr, mid+1, end,  T);

合并问题:

  如何将将二个有序数列合并。这个非常简单,只要从比较二个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数。

  如果有数列为空,那直接将另一个数列的数据依次取出即可。

 1         // 合并两个空间 
 2         while( p<=mid && q<=end){  // 两个子序列都不为空 
 3             if( arr[p] <= arr[q])  // 左半部分小于右半部分的数,
 4                 T[i++] = arr[p++];
 5             else
 6                 T[i++]  = arr[q++];
 7         }
 8         // 另一半不为空的数组直接插入到数组末尾
 9         while(p<=mid){
10             T[i++] = arr[p++];
11         }
12         while(q<=end){
13             T[i++] = arr[q++];
14         }
15         
16     
17         // 将临时数组拷贝回arr数组 
18         for( i=start; i<=end; i++){
19             arr[i] = T[i];
20         }

 

最后测试代码

 1 /**
 2 *  Merger Sort
 3 *  步骤:
 4 *   (1) 划分子空间;
 5 *   (2) 子空间排序; 
 6 *   (3) 合并子空间 
 7 */
 8 
 9 
10 #include <iostream> 
11 
12 using namespace std;
13 
14 
15 /*
16 *  mergerSort函数
17 *  参数: 
18 *      arr[]  :   待排序的数组
19 *      start  :   子空间排序的开始下标
20 *      end    :   子空间排序的结束下标
21 *      T[]    :   合并数组前的保存数据的临时数组 
22 */
23 void mergerSort(int arr[], int start, int end, int T[])
24 {
25     // 当子空间长度大于1时,需要重新划分 
26     if(end-start>0){                 
27           int i = start;                 // 临时数组的开始下标  
28         int mid = (end+start)/2;       // 划分子空间的中点 
29         int p=start, q=mid+1;             // 两个子空间的开始下标
30     
31         // 子空间递归求解 
32         mergerSort(arr, start, mid , T);
33         mergerSort(arr, mid+1, end,  T);
34         
35         
36         // 合并两个空间 
37         while( p<=mid && q<=end){  // 两个子序列都不为空 
38             if( arr[p] <= arr[q])  // 左半部分小于右半部分的数,
39                 T[i++] = arr[p++];
40             else
41                 T[i++]  = arr[q++];
42         }
43         // 另一半不为空的数组都是较大的值 
44         while(p<=mid){
45             T[i++] = arr[p++];
46         }
47         while(q<=end){
48             T[i++] = arr[q++];
49         }
50         
51     
52         // 将临时数组拷贝回arr数组 
53         for( i=start; i<=end; i++){
54             arr[i] = T[i];
55         }
56 
57     }
58 }
59 
60 int main()
61 {
62     int n;
63     int arr[1000];
64     int T[1000] ;
65     while(cin>>n){
66         for(int i=0;i<n;i++)
67             cin >> arr[i];
68         
69         mergerSort(arr,0,n-1,T);
70         
71         for(int i=0;i<n;i++){
72             cout << arr[i] << " ";
73         }cout<<endl;
74     }
75     return 0;
76 }

 

posted on 2016-04-19 15:55  skipping  阅读(234)  评论(0)    收藏  举报

导航