高等排序5
逆序数
数组a中,如果一组数满足
,且i<j,那么这组数就称为逆序数。
逆序数与冒泡排序法的交换次数相等。如果用冒泡排序法求逆序数,算法复杂度会达到O()。可以使用归并排序法来求逆序数,对数组l和数组r进行排序,分别求出各自的逆序数。在合并数组l和数组r时,如果l[i]>r[j],计算n1-i就能得到当前有多少个与r[j]相关的逆序数,最后将逆序数加起来。
代码如下:
#include<iostream>
#define max 999
using namespace std;
int cnt = 0;
int l[max / 2 + 2], r[max / 2 + 2];
int merge(int a[],int n,int left,int mid,int right) {
int n1, n2;
n1 = mid - left;
n2 = right - mid;
for (int i = 0; i < n1; i++) {
l[i] = a[left+i];
}
for (int i = 0; i < n2; i++) {
r[i] = a[mid + i];
}
l[n1] = r[n2] = max;
int i=0, j = 0;
for (int k = left; k < right; k++) {
if (l[i] <= r[j]) {
a[k] = l[i++];
}
else {
a[k] = r[j++];
cnt += n1 - i;
}
}
return cnt;
}
int mergesort(int a[], int n, int left,int right){
if (left + 1 < right) {
int mid, v1, v2, v3;
mid = (left + right) / 2;
v1 = mergesort(a, n, left, mid);
v2 = mergesort(a, n, mid, right);
v3 = merge(a, n, left, mid, right);
return v1 + v2 + v3;
}
else return 0;
}
int main() {
int n,a[max];
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
mergesort(a, n, 0, n);
for (int i = 0; i < n; i++) {
cout << a[i]<<" ";
}
cout << cnt;
return 0;
}
读《挑战程序设计竞赛》第十八天(侵删)2021.3.12
( 2021.7.10 第一次修改)