题目描述:
输入n个正整数,使用归并排序算法将它们按从小到大的顺序进行排序。
输入描述:
第一行一个整数n(1≤n≤1000),表示需要输入的正整数的个数;
第二行为用空格隔开的n个正整数(每个正整数均不超过1000)。
输出描述:
输出一行,表示输入的n个正整数。整数间用一个空格隔开,行末不允许有多余的空格。
样例:
输入:
5
2 8 5 1 3
输出:
1 2 3 5 8
归并排序的思路:
二路归并思想,先将序列归并为n/2个组,组内单独排序,再将其两两合并直至回归完成。时间复杂度为
O(nlogn)
。可以将归并排序拆分为两个部分:
① 拆分:将当前数组范围拆分为两个部分分别进行排序
② 组合:将两个分别排序好的数组范围按序组合在一起。
#include<stdio.h>
#define maxn 1001
// 组合,将数组A的[L1,R1]与[L2,R2]区间合并为有序区间,这块就是two pointers思想
void merge(int* A, int L1, int R1, int L2, int R2){
int i = L1, j = L2;
int temp[maxn], index = 0;
while(i <= R1 && j <= R2){
if(A[i] <= A[j]){
temp[index++] = A[i++];
}else{
temp[index++] = A[j++];
}
}
while(i <= R1) temp[index++] = A[i++];
while(j <= R2) temp[index++] = A[j++];
for(i = 0; i < index; i++){
A[L1 + i] = temp[i]; //将合并后的序列赋值回数组
}
}
// 拆分,将array数组当前区间[left,right]进行归并排序
void mergeSort(int A[], int left, int right){
if(left < right){
int mid = (left + right) / 2;
mergeSort(A, left, mid);
mergeSort(A, mid + 1, right);
merge(A, left, mid, mid + 1, right);
}
}
int main(){
int n;
int arr[maxn] = {};
scanf("%d", &n);
for(int i = 0; i < n; i++){
scanf("%d", &arr[i]);
}
mergeSort(arr, 0, n-1);
for(int i = 0; i < n; i++){
printf("%d", arr[i]);
if(i != n-1) printf(" ");
}
return 0;
}