zoukankan      html  css  js  c++  java
  • 刷题笔记-排序

    归并排序 -模板题

    思路:

    1.确定分界点 mid = l + r >> 2
    2.递归排序Left、Right部分
    3.使用双指针算法归并排序Left、Right部分

    代码:

    #include <cstdio>
    #include <iostream>
    using namespace std;
    
    const int N = 100010;
    int a[N],tmp[N];
    
    void merge_sort(int *a , int l, int r)
    {
        //如果子序列小于等于1,则返回
        if(l >= r)  return;
        int mid = l + r >> 1;
        //递归排序
        merge_sort(a, l, mid),  merge_sort(a, mid+1 , r);
        //归并合二为一
        int i = l, j = mid + 1, k = 0;
        while(i <= mid && j <= r)
            if(a[i] <= a[j])   tmp[k++] = a[i++];
            else tmp[k++] = a[j++];
        while(i <= mid)   tmp[k++] = a[i++];
        while(j <= r)     tmp[k++] = a[j++];
        //在放回原数组
        for(i = l, j = 0; i <= r; i++, j++)
            a[i] = tmp[j];
    }
    
    int main(void)
    {
        int n;
        cin >> n;
        for(int i = 0; i < n; i++)    cin >> a[i];
       
        merge_sort(a,0,n-1);
        
        for(int i = 0; i < n; i++)   cout << a[i] << ' ';
        
        return 0;
    }
    

    逆序对的数量

    思路:

    1.总的数量等于 Left边中逆序对的数量、Right边中逆序对的数量、Left、Right两边的元素共同组成的逆序对的数量
    2.如何求算Left、Right两边的元素共同组成的逆序对的数量?

    • 考虑Right中元素被放入tmp数组中,即表示此元素小于Left边中任意元素,所以有 ans += mid - i + 1;

    代码:

    #include <cstdio>
    #include <iostream>
    using namespace std;
    
    typedef long long int LL;
    
    const int N = 100010;
    int a[N],tmp[N];
    
    LL merge_sort(int *a , int l, int r)
    {
        //如果子序列小于等于1,则返回
        if(l >= r)  return 0;
        int mid = l + r >> 1;
        //递归排序
        LL res = merge_sort(a, l, mid) + merge_sort(a, mid+1 , r);
        //归并合二为一
        int i = l, j = mid + 1, k = 0;
        while(i <= mid && j <= r)
            if(a[i] <= a[j])   
            {
                tmp[k++] = a[i++];
            }
            else 
            {   
                res += (LL)mid - i + 1;
                tmp[k++] = a[j++];
            }
            
        while(i <= mid)   tmp[k++] = a[i++];
        while(j <= r)     tmp[k++] = a[j++];
        //在放回原数组
        for(i = l, j = 0; i <= r; i++, j++)
            a[i] = tmp[j];
        
        return res;
    }
    
    int main(void)
    {
        int n;
        cin >> n;
        for(int i = 0; i < n; i++)    cin >> a[i];
       
        LL ans = merge_sort(a,0,n-1);
        
        cout << ans << endl;
        
        return 0;
    }
    
  • 相关阅读:
    在windows下拆卸Linux就是这么俭朴
    打点Linux下永中Office和桌面殊效的冲突
    Banshee 0.11.4
    ubuntu8.0中文输入法
    RedFlag 6.0 硬盘安置我解
    阅读器和把持体系和用户的IQ
    初试Fedora,最后还是Xubuntu
    VMware中放置Ubuntu后鼠标滚轮标题问题办理
    GNOME 的文件经管器将片面支撑标签式阅读
    ATI显卡开启fedora9的3d后果的一些条记
  • 原文地址:https://www.cnblogs.com/zy200128/p/12673543.html
Copyright © 2011-2022 走看看