2.分并排序
2.分并排序
方法
1.确定分界点:mid (0+n)/2
2.递归排序left,right(分成两个数组)
3.(重点)归并---合二为一
用两个指针从开头比较
(稳定)
遇到相同的先把第一个输出,保证数组里的相同数的位置是不变的
先分成好几段
再和并
代码
优雅的分并
#include<iostream> using namespace std; const int N=1e6+10; int n; int q[N],tmp[N]; void merge_sort(int q[],int l,int r) { if(l>=r) return;//如果数组小于等于一个,直接出去 int mid=(l+r)>>1;//相当于除于二(把l+r看作二进制向右退一位,向下取整)(l+r<<1,相当于乘以2) merge_sort(q,l,mid),merge_sort(q,mid+1,r);//递归分成好多段 /*为什么不用 mid - 1 作为分隔线呢 即 merge_sort(q, l, mid - 1 ), merge_sort(q, mid, r) 因为 mid = l + r >> 1 是向下取整,mid 有可能取到 l (数组只有两个数时),造成无限划分 解决办法: mid 向上取整就可以了, 即 mid = l + r + 1 >> 1 */ int k=0,i=l,j=mid+1; while(i<=mid&&j<=r)//不能越过边境 if (q[i]<=q[j]) tmp[k++]=q[i++];//合并 else tmp[k++]=q[j++]; while(i<=mid) tmp[k++]=q[i++];//如果有一半有剩余的全给tmp数组 while(j<=r) tmp[k++]=q[j++]; for(i=l,j=0;i<=r;i++,j++) q[i]=tmp[j];//把tmp再还给q } int main() { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&q[i]); merge_sort(q,0,n-1); for(int i=0;i<n;i++)printf("%d ",q[i]); return 0; }