首先介绍一下逆序数的概念:在<线性代数>和<离散数学>提到过逆序数,逆序数的定义就是只要前面的数大于后面的数就算一次,然后遍历后统计总的次数便是逆序数,举个例子 1 9 5 8的逆序数,只有9大于5和8这两种情况,所以没有其他情况前面的数比后面大了,所以它的逆序数就为2。
再者介绍一下归并排序的算法:归并排序算法是一种基于比较的排序算法。它的基本思想是分治.首先根据中间位置(low + high) / 2分成两半,然后递归分别对左边一半(low,mid) 和 右边一半(mid+1,high)进行归并排序,最后对两个已排序好的一半进行和合并。归并排序的时间复杂度为O(nlogn),具体归并排序的算法思想可自行百度。
下面贴下求逆序数的代码和归并排序算法的模版以供大家参考学习,如果疏漏之处还望多多指教。
#include<iostream>
using namespace std;
const int size = 1000;
int invers = 0;//求逆序数
int tmp[size];
void Copy(int a[], int b[], int low, int high)
{
for (int i = low; i <= high; i++) a[i] = b[i];
}
void Merge(int a[],int b[],int low,int high)
{
int mid = (low + high) / 2;
int i, j, k;//i指向[low,mid],j指向[mid+1,high]
for (i = low,j = mid + 1, k = low; i <= mid && j <= high; k++)
{
if (a[i] < a[j]) b[k] = a[i++];//等价于b[k] = a[i];i++;
else
{
//前面大于后面的数,有逆序数
if (a[i] > a[j])
invers += mid - i + 1;
b[k] = a[j++];
}
}
while (i <= mid) b[k++] = a[i++];
while (j <= high) b[k++] = a[j++];
Copy(a,b,low,high);//将排好序的元素从b中复制给a
}
void MergeSort(int a[], int low, int high)
{
if (low >= high) return;
int mid = (low + high) / 2;
MergeSort(a,low,mid); //分成两部分
MergeSort(a,mid+1,high);
Merge(a,tmp,low,high);
}
int main()
{
int arr[size], N, i;
while (cin >> N)
{
invers = 0;
for (i = 0; i < N; i++)
{
cin >> arr[i];
}
MergeSort(arr,0,N-1);
for (i = 0; i < N - 1; i++)
{
cout << arr[i] << " ";
}
cout << arr[i] << endl;
cout << "inverse number is " << invers << endl;
}
return 0;
}