• 归并排序 & 逆序对


    归并排序

    动画演示:

    请添加图片描述

    图示含义
    ■ 的柱形代表尚未排好序的数
    ■ 的柱形代表已经排好序的数
    其他颜色 ■ 的柱形正在递归、归并中的数

    我们发现,首先将 「 8个元素 」 分成 「 4个元素 」,再将 「 4个元素 」分成 「 2个元素 」,然后 「比较」「 2个元素 」的值,使其在自己的原地数组内有序,然后两个 「 2个元素 」 的数组归并变成 「 4个元素 」「升序」数组,再将两个「 4个元素 」 的数组归并变成 「 8个元素 」「升序」数组。

    归并排序代码如下:

    const int N = 100009;
    int n, s[N], t[N];
    void msort(int l, int r)
    {
        if (l >= r)
            return ;
        int mid = l + r >> 1;
        msort(l, mid), msort(mid + 1, r);
        int h1 = l, h2 = mid + 1, idx = l;
        while (h1 <= mid && h2 <= r)
            t[idx++] = (s[h1] <= s[h2] ? s[h1++] : s[h2++]);
        while (h1 <= mid)
            t[idx++] = s[h1++];
        while (h2 <= r)
            t[idx++] = s[h2++];
        for (int i = l; i <= mid; i++)
            s[i] = t[i];
        for (int i = mid + 1; i <= r; i++)
            s[i] = t[i];
    }
    void solve()
    {
        cin >> n;
        for (int i = 1; i <= n; i++)    cin >> s[i];
        msort(1, n);
        for (int i = 1; i <= n; i++)
            cout << s[i] << " \n"[i == n];
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    归并排序求逆序对

    我们在归并排序的过程中就可以计算逆序对的个数
    左边头元素 > > > 右边头元素
    逆 序 对 个 数 + = m i d − 左 边 头 位 置 + 1 逆序对个数 += mid - 左边头位置 + 1 +=mid+1

    归并排序求逆序对代码:

    const int N = 1000009;
    int n, s[N], t[N];
    long long ans = 0;
    void msort(int l, int r)
    {
        if (l >= r)
            return;
        int mid = l + r >> 1;
        msort(l, mid), msort(mid + 1, r);
        int h1 = l, h2 = mid + 1, idx = l;
        while (h1 <= mid && h2 <= r)
        {
            if (s[h1] <= s[h2])
                t[idx++] = s[h1++];
            else    
                t[idx++] = s[h2++], ans += mid - h1 + 1;
        }
        while (h1 <= mid)
            t[idx++] = s[h1++];
        while (h2 <= r)
            t[idx++] = s[h2++];
        for (int i = l; i <= mid; i++)
            s[i] = t[i];
        for (int i = mid + 1; i <= r; i++)
            s[i] = t[i];
    }
    void solve()
    {
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> s[i];
        msort(1, n);
    
        cout << ans << '\n';
    }
    int main()
    {
        buff;
        solve();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
  • 相关阅读:
    有趣的 scanf()
    能耗管理系统在煤矿行业中的应用
    微信小程序数据传递的方式-页面数据的存取
    DSPE-PEG-Silane DSPE-PEG-SIL 磷脂-聚乙二醇-硅烷疏水性18碳饱和磷脂
    说一下vue响应式原理?可不只有proxy
    云存储服务OneDrive捆绑系统销售,30多家欧洲公司投诉微软垄断
    【知网研学】使用方法
    linux centos7 安装nginx
    Sanic​——Python函数变成API的神器
    MySQL如何避免全表扫描?
  • 原文地址:https://blog.csdn.net/m0_60593173/article/details/128105999