归并排序 逆序数 分治

归并排序 

图来自维基

2016-07-15_归并排序.gif

递归调用的过程需要在脑中模拟清楚

然后是代码的细节问题 

多复习多理解

#include <iostream>
using namespace std;
long long ans = 0;
void merge(int a[], int L, int M, int R)
{
	int leftlen = M - L;
	int rightlen = R - M + 1;
	int left[leftlen];
	int right[rightlen];
	int i , j , k;
	for(i = L; i < M; i++)
	{
		left[i - L] = a[i];
	}
	for(i = M; i <= R; i++)
	{
		right[i - M] = a[i];
	}
	i = 0; j = 0; k = L;
	while(i < leftlen && j < rightlen)
	{
		if(left[i] < right[j])
		{
			a[k++] = left[i++];
		}
		else
		{
			a[k++] = right[j++];
			ans += leftlen - i;
		}
	}
	while(i < leftlen)
	{
		a[k++] = left[i++];
	}
	while(j < rightlen)
	{
		a[k++] = right[j++];
	}
}
void merge_sort(int a[], int L, int R)
{
	if(L == R)
		return ;
	else
	{
		int M = (R + L) / 2;
		merge_sort(a, L, M); //递归分解左侧
		merge_sort(a, M + 1, R); //递归分解右侧
		merge(a,L,M + 1,R); //合并
	}
}
int main()
{
	ios::sync_with_stdio(false);
	int a[50010];
	int n;
	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]<<endl;
	}
	cout<<endl;
	cout<<ans<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zeolim/article/details/80069794