总时间限制: 2000ms 单个测试点时间限制: 500ms 内存限制: 65536kB
描述
随机输入一组数,使用归并排序得到从小到大的序列。
输入
第1行是元素的个数,第2行是各个元素的值,每个元素以空格分隔。
输出
输出有1行,即排完序后由小到大的序列,每个元素之间以空格分隔。
样例输入1
5
9 7 8 5 3
样例输出1
3 5 7 8 9
样例输入2
10
9 8 7 6 5 4 3 2 1 6
样例输出2
1 2 3 4 5 6 6 7 8 9
思路
这个分治要借助递归思想:
- 递归形式: 把数组分成两半,对每一半再来一次归并排序
- 递归边界:当元素只剩一个时,停止递归
- 合并:把上一次数组按从小到大的顺序抄到新数组里
代码
// Using C99 standard
#include <stdio.h>
void MergeSort(int*, int, int, int*);
void Merge(int*, int, int, int, int*);
int main() {
int number;
scanf("%d", &number);
int array[number], tmp[number];
for(int i = 0; i < number; i++) {
scanf("%d", &array[i]);
}
MergeSort(array, 0, number - 1, tmp);
for(int i = 0; i < number; i++) {
printf("%d ", array[i]);
}
printf("\n");
return 0;
}
void Merge
(int a[], int start, int middle, int end, int tmp[]) {
int pb = 0;
int p1 = start, p2 = middle + 1;
while( p1 <= middle && p2 <= end) {
if( a[p1] < a[p2] )
tmp[pb++] = a[p1++];
else
tmp[pb++] = a[p2++];
}
while( p1 <= middle )
tmp[pb++] = a[p1++];
while( p2 <= end )
tmp[pb++] = a[p2++];
/* Copy back to a[] */
for(int i = 0; i < end-start+1; i++)
a[start+i] = tmp[i];
}
void MergeSort(int a[], int start, int end, int tmp[]) {
if( start < end ) {
int middle = start + (end - start)/2; // same as (start + end)/2, in case of overflow
MergeSort(a, start, middle, tmp);
MergeSort(a, middle+1, end, tmp);
Merge(a, start, middle, end, tmp);
}
}