【模板】归并排序(逆序对)

归并排序模板

#include
using namespace std;
int a[100005];
void merge(int l,int r){
	int mid=(l+r)/2;
	int aux[r-l+1];
	for(int i=l;i<=r;i++){
		aux[i-l]=a[i];
	}//第一步:复制该数组[l,r]部分 
	int i1=l,i2=mid+1;//第二步:双指针 
	for(int i=l;i<=r;i++){//第三步:如果其中一半的指针已经到头,就直接加入另一半;否则,就对两指针指向的元素进行比较 
		if(i1>mid){
			a[i]=aux[i2-l];
			i2++;
		}else if(i2>r){
			a[i]=aux[i1-l];
			i1++;
		}else if(aux[i1-l]>aux[i2-l]){
			a[i]=aux[i2-l];
			i2++;
		}else{
			a[i]=aux[i1-l];
			i1++;
		}
	}
}
void mergesort(int l,int r){//分治:先分后合的递归 
	if(l>=r) return;//注意跳出条件:l>=r 
	int t=(l+r)/2;
	mergesort(l,t);
	mergesort(t+1,r);
	merge(l,r);
}
int main(){
	int n;
	cin>>n;
	for(int i=0;i<n;i++) cin>>a[i];
	mergesort(0,n-1);
	for(int i=0;i<n;i++) cout<<a[i]<<' ';
}

例子:逆序对

	for(int i=l;i<=r;i++){//第三步:如果其中一半的指针已经到头,就直接加入另一半;否则,就对两指针指向的元素进行比较 
		if(i1>mid){
			a[i]=aux[i2-l];
			i2++;
		}else if(i2>r){
			a[i]=aux[i1-l];
			i1++;
			ans+=i2-mid-1;
		}else if(aux[i1-l]>aux[i2-l]){//取等号错:只有i2严格小于i1时,进i2,保证i1前面的i2都是严格小于它的 
			a[i]=aux[i2-l];
			i2++;
		}else{
			a[i]=aux[i1-l];
			i1++;
			ans+=i2-mid-1;
		}
	}//当插入i1(左半边指针时)加上左边插入过的,右半边元素的个数。 
//之所以能够这样算,是因为归并排序保证了每半边的有序性。 

你可能感兴趣的:(算法,算法,c++,排序算法)