- 暴力
对每个数遍历它之前的所有数有比它大的逆序数就加一 - 利用归并排序
每改变一次排序逆序数就加一
int temp[100]; //存储已排序的数组
int ans; //代表逆序数的个数
int a[100] = { 1,8,6,3,4,2}; //存储原数组信息
void merge(int i, int mid, int j)
{
int left = i;
int right = j;
int m = mid + 1;
int t = i; //递增temp数组的插入元素位置
while (left <= mid && m <= j)
{ //两部分数组都没到尽头
if (a[left] > a[m])
{
temp[t++] = a[m++];
ans += mid - left + 1; //前面区间全部比a[m]大
}
else
temp[t++] = a[left++];
}
while (left <= mid)
{ //后面数组已没有元素
temp[t++] = a[left++];
}
while (m <= j)
{
temp[t++] = a[m++];
}
for (int k = i; k <= j; k++)
{ //把数组替换到a数组中
a[k] = temp[k];
}
}
void mergesort(int i, int j)
{
if (i < j)
{
int mid = (j + i) / 2;
mergesort(i, mid);
mergesort(mid + 1, j);
merge(i, mid, j);
}
}
3.树状数组
先在数组中放最大的元素
然后判断前面已经放置了几个元素了
然后放第二大,再判断前面有几个
依次类推
int aa[maxn];
int c[maxn]; //树状数组
int n;
struct Node
{
int v;
int order;
}a[maxn];
bool cmp(Node a, Node b)
{
return a.v < b.v;
}
int lowbit(int k)
{
return k&(-k);
}
void update(int t, int value)
{ //即一开始都为0,一个个往上加(+1),
int i;
for (i = t; i <= n; i += lowbit(i))
c[i] += value;
}
int getsum(int t)
{ //即就是求和函数,求前面和多少就是小于它的个数
int i, sum = 0;
for (i = t; i >= 1; i -= lowbit(i))
sum += c[i];
return sum;
}
int main()
{
int i;
while (scanf("%d", &n), n)
{
for (i = 1; i <= n; i++)
{
scanf("%d", &a[i].v);
a[i].order = i;
}
sort(a + 1, a + n + 1,cmp);
memset(c, 0, sizeof(c));
for (i = 1; i <= n; i++)
aa[a[i].order] = i;
int ans = 0;
for (i = 1; i <= n; i++)
{
update(aa[i], 1);
ans += i - getsum(aa[i]);
}
printf("%d\n", ans);
}
return 0;