【剑指Offer】题36:数组中的逆序对

本文介绍了一种使用归并排序算法来计算数组中逆序对总数的方法,并提供了详细的C语言实现代码。通过递归地将数组分为更小的部分进行排序和合并,在合并过程中计算逆序对数量。
题目描述:
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
输入:
每个测试案例包括两行:
第一行包含一个整数n,表示数组中的元素个数。其中1 <= n <= 10^5。
第二行包含n个整数,每个数组均为int类型。
输出:
对应每个测试案例,输出一个整数,表示数组中的逆序对的总数。

样例输入:

4
7 5 6 4

样例输出:

5

#include <stdio.h>
#include <stdlib.h>
 
typedef struct list {
    int Size; 
    int *Elements;
}List;
 
void Merge(List *list ,int Temp[],int i1,int j1,int i2 ,int j2,long long int *num) {
    int i=j1,j=j2;
    int size=j2-i1;
 
    while((i>=i1)&&(j>=i2)) {
        if(list->Elements[i]>list->Elements[j]) {
            Temp[size--]=list->Elements[i--];
            *num=*num+j-i2+1;
        }else {
            Temp[size--]=list->Elements[j--];
        }
     
    }
    while(i>=i1)Temp[size--]=list->Elements[i--];
    while(j>=i2)Temp[size--]=list->Elements[j--];
 
}
void MergeSort(List *list,int n ) {
    int *Temp;
    int i1,j1,i2,j2,i,size=1,k=0;
    long long int num=0;
    Temp = (int*)malloc(n*sizeof(int));
 
    while(size<list->Size) {
        i1=0;
        k=0;
        while(i1+size<list->Size) {
            i2=i1+size;
            j1=i2-1;
            if(i2+size-1>list->Size-1)j2=list->Size-1;
            else j2=i2+size-1;
 
            Merge(list,Temp,i1,j1,i2,j2,&num);
 
            for(i=0;i<j2-i1+1;i++){
                list->Elements[k+i]=Temp[i];
            }
 
            k=k+j2-i1+1;
 
            i1=j2+1;        
        }
        size*=2;
         
    }
    free(Temp);
    printf("%lld\n",num);//最后输出格式加上11d才AC 
     
}
List CreateList(int n) {
    List ls ;
    int i ;
    ls.Size=n;
    ls.Elements = (int*)malloc(n*sizeof(int));
    for(i=0;i<n;i++) {
        scanf("%d",&ls.Elements[i]);
    }
    return ls;
}   
 
int  main() {
    int n ;
    List list;
    while(scanf("%d",&n)!=EOF) {
        list=CreateList(n);
        MergeSort(&list,n);
        free(list.Elements);
         
    }
    return 1;   
}
/**************************************************************
    Problem: 1348
    User: tcals
    Language: C
    Result: Accepted
    Time:100 ms
    Memory:1696 kb
****************************************************************/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值