ACM—归并求逆序数(归并排序的应用)

数据结构实验之排序五:归并求逆序数

Time Limit: 50 ms Memory Limit: 65536 KiB

Submit Statistic

Problem Description

对于数列a1,a2,a3…中的任意两个数ai,aj (i < j),如果ai > aj,那么我们就说这两个数构成了一个逆序对;在一个数列中逆序对的总数称之为逆序数,如数列 1 6 3 7 2 4 9中,(6,4)是一个逆序对,同样还有(3,2),(7,4),(6,2),(6,3)等等,你的任务是对给定的数列求出数列的逆序数。

Input

输入数据N(N <= 100000)表示数列中元素的个数,随后输入N个正整数,数字间以空格间隔。

 

Output

输出逆序数。

Sample Input

10
10 9 8 7 6 5 4 3 2 1

Sample Output

45

Hint

Source

xam

SDUTACM运维技术中心

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
long int count;
/* data[left...mid] and data[mid+1...right] */
void mergeit(int data[],int left,int mid,int right,int reserve[])
{
    int i=left,j=mid+1; //  the start location
    int m=mid,n=right;  //  the end location
    int k=0;//  count
    while(i<=m&&j<=n)
    {
        if(data[i]<=data[j])
            reserve[k++]=data[i++];
        else
        {
            reserve[k++]=data[j++];
            count+=mid-i+1;
        }
    }
    while(i<=m)
        reserve[k++]=data[i++];
    while(j<=n)
        reserve[k++]=data[j++];
    for(i=0; i<k; i++) // return the data that has ordered
        data[left+i]=reserve[i];
}
void mergesort(int data[],int left,int right,int reserve[])
{
    if(left<right)
    {
        int mid=(left+right)/2;     // SET THE MID
        mergesort(data,left,mid,reserve);  // merge the left
        mergesort(data,mid+1,right,reserve);   //  merge the right
        mergeit(data,left,mid,right,reserve); // MERGE THE DATA
    }

}
int main()
{
    int data[123456];
    int reserve[123456];
    memset(data,0,sizeof(data));
    memset(reserve,0,sizeof(reserve));
    int n;
    scanf("%d",&n);
    int i;
    for(i=0; i<n; i++)
        scanf("%d",&data[i]);
    mergesort(data,0,n-1,reserve);
    printf("the result of the merge order:\n");
    for(i=0; i<n; i++)
        printf("%d ",data[i]);
    printf("\nthe number of the inverse is %ld\n",count);
    return 0;
}

1.归并排序:将两个或者两个以上的有序子序列“归并”为一个有序数列。

                                                           【 52     23     80     36     68     14 】

                                            【 52   23   80 】                                       【 36   68   14 】  

                                    【 52  23 】      【 80 】                                 【 36   68 】     【 14 】 

                                 【 52 】    【 23 】    【 80 】                         【 36 】   【 68 】  【 14 】

                                       【 23  52 】  【 80 】                                           【 36 68 】  【 14 】

                                         【 23   52   80 】                                                 【 14    26   68 】

                                                           【 14      23     36     38     52     80 】

2.性质相同,规模更小,采用递归。

3.逆序数在合并数组时计数求得。

(希望可以帮到你一点!)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值