刷题笔记-排序

归并排序 -模板题

思路:

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;
}
原文地址:https://www.cnblogs.com/zy200128/p/12673543.html