总时间限制: 2000ms 单个测试点时间限制: 500ms 内存限制: 65536kB

描述

随机输入一组数,使用归并排序得到从小到大的序列。

输入

第1行是元素的个数,第2行是各个元素的值,每个元素以空格分隔。

输出

输出有1行,即排完序后由小到大的序列,每个元素之间以空格分隔。

样例输入1

  1. 5
  2. 9 7 8 5 3

样例输出1

  1. 3 5 7 8 9

样例输入2

  1. 10
  2. 9 8 7 6 5 4 3 2 1 6

样例输出2

  1. 1 2 3 4 5 6 6 7 8 9

思路

这个分治要借助递归思想:

  • 递归形式: 把数组分成两半,对每一半再来一次归并排序
  • 递归边界:当元素只剩一个时,停止递归
  • 合并:把上一次数组按从小到大的顺序抄到新数组里

例题-归并排序 - 图1

代码

  1. // Using C99 standard
  2. #include <stdio.h>
  3. void MergeSort(int*, int, int, int*);
  4. void Merge(int*, int, int, int, int*);
  5. int main() {
  6. int number;
  7. scanf("%d", &number);
  8. int array[number], tmp[number];
  9. for(int i = 0; i < number; i++) {
  10. scanf("%d", &array[i]);
  11. }
  12. MergeSort(array, 0, number - 1, tmp);
  13. for(int i = 0; i < number; i++) {
  14. printf("%d ", array[i]);
  15. }
  16. printf("\n");
  17. return 0;
  18. }
  19. void Merge
  20. (int a[], int start, int middle, int end, int tmp[]) {
  21. int pb = 0;
  22. int p1 = start, p2 = middle + 1;
  23. while( p1 <= middle && p2 <= end) {
  24. if( a[p1] < a[p2] )
  25. tmp[pb++] = a[p1++];
  26. else
  27. tmp[pb++] = a[p2++];
  28. }
  29. while( p1 <= middle )
  30. tmp[pb++] = a[p1++];
  31. while( p2 <= end )
  32. tmp[pb++] = a[p2++];
  33. /* Copy back to a[] */
  34. for(int i = 0; i < end-start+1; i++)
  35. a[start+i] = tmp[i];
  36. }
  37. void MergeSort(int a[], int start, int end, int tmp[]) {
  38. if( start < end ) {
  39. int middle = start + (end - start)/2; // same as (start + end)/2, in case of overflow
  40. MergeSort(a, start, middle, tmp);
  41. MergeSort(a, middle+1, end, tmp);
  42. Merge(a, start, middle, end, tmp);
  43. }
  44. }