归并排序
归并排序主要分为三步:
划分问题: 把序列分为元素个数尽量相等的两半;
递归求解: 把两半元素分别进行排序
合并问题: 把两个有序表合并成一个;
其中前两部分比较容易,关键是第三部分合并数组;
归并函数 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 }