【总结】归并排序
【总结】 归并排序
归并排序和冒泡排序,选择排序,桶排等一样属于排序方式
优点:
归并排序是一种稳定的排序方式
时间复杂度同快速排序一样为O(nlogn)
缺点:
需要O(n)的辅助空间
然后就是算法实现的具体流程辣
(图片来自百度百科
1.拆分
对于一个序列,我们每次将它分为两部分
对于每一部分再依次执行相同的操作,直到都分为单个的数字
2.归并
分为单个的数字之后,我们再对相邻两个数字进行合并
小的数字在前,大的数字在后
这样就合并为每组有两个数字的几组数
再对相邻的两组数进行归并,按照这种方法依次合并下去
由于再进行合并的两组数列都是有序的,我们用两个指针分别记录每一组数比较到的位置,比较两组数中指针分别所指的位置的数,将较小的数记录下来,指向他的指针指到下一个数。依次进行这种操作直到两组数都合并完。
Code
#include<iostream> #include<cstdio> using namespace std; int read(){ int a = 0,f = 0;char p = getchar(); while(!isdigit(p)){f|p=='-';p = getchar();} while(isdigit(p)){a = (a << 3) + (a << 1) + (p^48);p = getchar();} return f?-a:a; } int a[500001],b[5000001]; long long ans; void _Solve(int l1,int r1,int l2,int r2){ int k1 = l1,k2 = l2,zz = l1;//两个指针 while(k1 <= r1 && k2 <= r2){//直到有一个归并完 if(a[k1] <= a[k2] ){ b[zz] = a[k1]; k1 ++;zz++; //ans++; } if(a[k1] > a[k2] ){ b[zz] = a[k2]; k2 ++;zz++; ans += r1-k1+1 ; } } if(k1 <= r1)for(int i = zz;i <= r2;i ++)b[i]=a[k1++]; if(k2 <= r2)for(int i = zz;i <= r2;i ++)b[i]=a[k2++]; //cout<<l1<<" "<<r2<<" "; for(int i = l1;i <= r2;i ++){ //cout<<"hhh"<<b[i]<<" "; a[i] = b[i]; } //cout<<endl; } void Sortt(int l,int r){ //cout << l <<" "<< r <<endl; if(l < r){ int mid = (l+r)/2; Sortt(l,mid); Sortt(mid +1,r); _Solve(l,mid,mid+1,r); } return; } int main(){ int n; n = read(); for(int i = 1;i <= n;i ++){ a[i] = read(); } Sortt(1,n); for(int i = 1;i <= n;i++)cout<<a[i]<<" "; }
emmm
补充
在进行归并排序的过程中,我们可以统计出序列的逆序对数(上一份代码中的ans便为序列的逆序对数)
相关推荐
nongfusanquan0 2020-08-18
Broadview 2020-07-19
数据与算法之美 2020-07-05
Masimaro 2020-06-21
wonner 2020-06-17
Oudasheng 2020-06-04
从零开始 2020-06-05
清溪算法君老号 2020-06-01
风吹夏天 2020-05-26
yangjingdong00 2020-05-11
Tips 2020-04-30
troysps 2020-04-26
ustbfym 2020-04-25
清溪算法君老号 2020-04-24
dushine00 2020-04-19
数据与算法之美 2020-04-18
wulaxiaohei 2020-04-17
nurvnurv 2020-04-16