题目描述
给定你一个长度为n的整数数列。
请你使用归并排序对这个数列按照从小到大进行排序。
并将排好序的数列按顺序输出。
输入格式
输入共两行,第一行包含整数 n。
第二行包含 n 个整数(所有整数均在1~109109范围内),表示整个数列。
输出格式
输出共一行,包含 n 个整数,表示排好序的数列。
数据范围
1≤n≤100000
样例
5
3 1 2 4 5
输出样例
1 2 3 4 5
(归并排序) $O(nlogn)$
核心思想:分治,和快排的区别是先递归处理,再合并
Step1: 找分界点mid
Step2: 递归左边left, 递归右边right
Step3: 合并左右left/right两个有序数组,借助于tmp数组
时间复杂度
$O(nlogn)$
C代码
#include<stdlib.h>
#include<stdio.h>
#define LEN 100010
int a[LEN];
int n;
int tmp[LEN];
void merge_sort(int a[], int l, int r){
if(l >= r) return ;
int mid = (l + r) >> 1;
merge_sort(a, l, mid);
merge_sort(a, mid + 1, r);
int k = 0, i = l, j = mid + 1;
while(i <= mid && j <= r){
if(a[i] <= a[j]) tmp[k++] = a[i++];
else tmp[k++] = a[j++];
}
while(i <= mid){
tmp[k++] = a[i++];
}
while(j <= r){
tmp[k++] = a[j++];
}
for(int i = l, j = 0; j <= k - 1; ){
a[i++] = tmp[j++];
}
}
int main(){
scanf("%d", &n);
for(int i = 0; i <= n - 1; i++){
scanf("%d", &a[i]);
}
merge_sort(a, 0, n - 1);
for(int i = 0; i <= n - 1; i++){
printf("%d ", a[i]);
}
}