归并排序,可分为递归(分解)和合并两个操作过程.
1.递归操作过程(分解序列)
- 将一个序列分成两个序列
- 将两个序列分成四个序列
- ...
- 直到将长度为n的序列分为n个不可再分的子序列后停止再分,此时每个子序列中都只含有1个元素.可视该子序列为一个有序序列.
- 对两两相邻的两个有序子序列进行合并操作,得到的每个有序序列中都含有2个元素.
- 将得到的有序序列再次进行合并操作,得到的每个有序序列中都含有4个元素.
- ...
- 直到合并了所有的有序序列时为止,则得到了结果.
2.合并操作过程(合并序列)
- 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
- 设定两个指针,最初位置分别为两个已经排序序列的起始位置
- 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
- 重复步骤3直到某一指针达到序列尾
- 将另一序列剩下的所有元素直接复制到合并序列尾
C++代码如下:
1 #include<stdio.h> 2 3 // 将两个有序序列进行合并 4 void Merge(int arr[], int first, int mid, int last) 5 { 6 int i1 = first; 7 int i2 = mid + 1; 8 int m = mid; 9 int n = last; 10 int i3 = 0; 11 12 int *temp = new int[last - first + 1]; 13 14 while(i1 <= m && i2 <= n) 15 { 16 if (arr[i1] < arr[i2]) 17 temp[i3++] = arr[i1++]; 18 else 19 temp[i3++] = arr[i2++]; 20 } 21 while(i1 <= m) 22 temp[i3++] = arr[i1++]; 23 while(i2 <= n) 24 temp[i3++] = arr[i2++]; 25 for(i1=0; i1<i3; i1++) 26 arr[first + i1] = temp[i1]; 27 28 delete [] temp; 29 30 } 31 32 void MergeSort(int arr[], int first, int last) 33 { 34 if (first < last) 35 { 36 int mid = (first + last) / 2; 37 MergeSort(arr, first, mid); 38 MergeSort(arr, mid + 1, last); 39 Merge(arr, first, mid, last); 40 } 41 } 42 43 // 在主函数中测试 44 void main() 45 { 46 int arr[] = {9, 1, 6, 5, 7, 3, 8, 2, 4, 0}; 47 MergeSort(arr, 0, 9); 48 // 输出排序后数组的内容 49 for(int i=0; i<10; i++) 50 printf("%d ", arr[i]); 51 52 getchar(); 53 }