基本思想:
归并与快排的想法都是分而治之,与快排不同的是,快排是先以一个基准来将大于和小于它的排到两侧,然后递归处理两侧直到所有的都排好序了,而归并则是先递归分离,然后两两按序合并最后得到一个有序的排列。
分离时我们通过递归从中间开始划分为左右两个区间,直到划分至只有一个元素,此时l≥r,然后回溯进行排序,按照各值的大小不断的合二为一,用一个额外数组来间接存储
图例:
给定你一个长度为 n 的整数数列。
请你使用归并排序对这个数列按照从小到大进行排序。
并将排好序的数列按顺序输出。
输入格式
输入共两行,第一行包含整数 n。
第二行包含 n 个整数(所有整数均在 1∼10^9 范围内),表示整个数列。
输出格式
输出共一行,包含 n 个整数,表示排好序的数列。
数据范围
1≤n≤100000
输入样例:
5
3 1 2 4 5
输出样例:
1 2 3 4 5
//首先确定分界点,与快速排序不同,先递归再排序 #include<iostream> using namespace std; const int N = 100010; int n, a[N], tmp[N];//与快速排序相比需要额外用到一个数组来存储归并 //归并排序的时间复杂度一般为O(nlogn) 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++];//这两个while是将剩下的全部拿过去 for(int i=l,j=0;i<=r;i++,j++) a[i]=tmp[j]; } int main() { cin>>n; for(int i=0;i<n;i++) cin>>a[i]; merge_sort(a,0,n-1); for(int i=0;i<n;i++) cout<<a[i]<<" "; return 0; }
例题: