归并排序加例题

本文介绍了归并排序的分治思想,并通过一个实例详细解释了排序过程。同时,提出了一道利用归并排序求逆序对的题目,强调在没有使用STL的情况下,理解排序算法的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

归并排序,采用的是分治的思想,例如:

0 4 2 1 3

这个数组,先分成两部分

0 4 和 2 1 3

再分成两部分

0  和  4  和  2   和  13

最后则

0 和 4 和 2 和 1 和  3

然后, 建立新数组

0 和 4,0小于4

则新数组为0 4

同理可得  1  3

则可得0 4 和 2 和 1 3

再建立新数组,对比0  4 和 2

显然,0 小于2,新数组0

再对比4 和2,2 小于4,则新数组0 2

最后剩下个4,则新数组0 2 4

再对比0 2 4 和 1 3 

原理同上,最后得到

0 1 2 3 4


给一道求逆序的例题,利用的便是归并排序的原理,第一次个人排位赛没A出来,因为还没学归并排序(“万恶”的STL太方便了)


帮挂科

Time Limit: 2000/1000ms (Java/Others)

Problem Description:

冬瓜发现期末很多人都挂了线代,他决定写个程序帮挂科的同学。在一个排列中,如果一对数的前后位置与大小
顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。
可是冬瓜想的头发都掉光了,聪明的你肯定能够帮帮他。

Input:

输入有多组
第1行:N,N为序列的长度(n <= 50000)
第2 - N + 1行:序列中的元素(0 <= A[i] <= 10^9)

Output:

输出逆序数

Sample Input:

4
2
4
3
1

Sample Output:

4



附上AC代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int temp[55555];
ll ans = 0;
void unio(int l1[],int s1,int l2[],int s2)
{
    int i,j,k;
    i = j = k = 0;
    while(i < s1 && j < s2)
    {
        if(l1[i] > l2[j])
        {
            ans+=s1-i;
            temp[k++] = l2[j++];
        }
        else
            temp[k++] = l1[i++];
    }
    while(i < s1)
        temp[k++] = l1[i++];
    while(j < s2)
        temp[k++] = l2[j++];
    for(int i = 0;i < k;i++)
        l1[i] = temp[i];
}
void divi(int l[],int s)
{
    if(s > 1)
    {
        int *l1 = l;
        int s1 = s/2;
        int *l2 = l+s1;
        int s2 = s-s1;
        divi(l1,s1);
        divi(l2,s2);
        unio(l1,s1,l2,s2);
    }
}
int main()
{
    int n;
    while(cin >> n)
    {
        ans = 0;
        int a[n];
        for(int i = 0;i < n;i++)
            cin >> a[i];
        divi(a,n);
        cout << ans <<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值