基础的归并排序
#include <iostream>
#include<cstring>
using namespace std;
const int n = 10000;
void merge(int a[], int s, int e, int m, int temp[]) //排序部分
{
int p1 = s, p2 = m + 1; //两个标记分别指向数组的前后两部分
int pd = 0; //指向临时数组的开头
while(p1 <= m&& p2 <= e)
{
if(a[p1] > a[p2]) //按次序比较前后两部分数字的大小,大的放到临时数组里面。
temp[pd++] = a[p1++];
else
temp[pd++] = a[p2++];
} //出循环意味着至少有一个数组已经全部排入临时数组
while(p2 <= e) //把没有排入的数组全部放进临时数组的尾部
temp[pd++] = a[p2++];
while(p1 <= m)
temp[pd++] = a[p1++];
for(int i = 0; i <= e - s; ++i)
{
a[i + s] = temp[i]; //把临时数组复制回原数组,用于之后的运算
}
}
int nx(int a[], int s, int e, int m, int &ans) //求逆序数
{
int i = s;
int j = m + 1;
while(i <= m&&j <= e) //比较大小来找出前半数组中比后半数组大的数
{
if(a[i] > a[j])
{
for(int f = j; f <= e; ++ f) //如果前面数组的一个数比后面数组的某一个数大,则前面的那个数比之后的所有数都大。
++ans; //逆序数加一
++i; //开始比较前面数组的后一个数字
}
else
{
++j; //不构成逆序数,继续比较后面的数字
}
}
return ans;
}
void mergesort(int a[], int s, int e,int temp[],int &ans) //分治部分
{
if(e > s)
{
int m = s + (e - s)/2; //找出中点
mergesort(a, s, m, temp, ans); //对前半部分分治
mergesort(a, m+1, e, temp, ans); //对后半部分分治
nx(a, s, e, m,ans); //分治完以后先求逆序数
merge(a, s, e, m, temp); //然后再排序
}
}
int main()
{
int ans = 0;
int a[20] = {1,2,3,4,5,6,7,8,91,10,18,12,13,14,15,16,17,18,19,20};
int temp[20];
mergesort(a, 0, 19, temp, ans);
for(auto c: temp)
cout << c << endl;
cout << "nx" << ans <<endl;
return 0;
}