归并排序及快速排序

两种常用的排序方式

1.归并排序

核心思想:分治
①递归排序 \(left\) \(right\) 此时前后两边都有序了
②归并排序 将两边最小的一个放到一个新数组中

//具体动图在这
https://www.runoob.com/wp-content/uploads/2019/03/mergeSort.gif


//核心代码
int q[N],tmp[N];
int merge_sort(int q[],int l,int r){
    if(l>=r) return ;
    int mid=(l+r)>>1;
    merge_sort(q,l,mid);
    merge_sort(q,mid+1,r);
    int k=0,i=l,j=mid+1;
    while(i<=mid&&j<=r){
        if(q[i]<=q[j]) tmp[k++]=q[i++];
        else tmp[k++]=q[j++];
    }
    while(i<=mid) tmp[k++]=q[i++];
    while(j<=r) tmp[k++]=q[j++];
    for(int i=l,j=0;i<=r;i++,j++) q[i]=tmp[j];
}
//一定要用手模拟一遍,用指针走一遍

归并排序求逆序对

在每次比较时如果发现大于的直接加上mid-i+1即可
具体去看其他博客

#include<iostream>
using namespace std;
int a[500010];
int tmp[500010];
int n;
long long ans=0;
void merge_sort(int q[],int l,int r){
    if(l>=r) return;
    int mid=(l+r)>>1;
    merge_sort(q,l,mid);
    merge_sort(q,mid+1,r);
    int i=l,j=mid+1;
    int k=0;
    while(i<=mid&&j<=r){
        if(q[i]>q[j]) tmp[k++]=q[j++],ans+=mid-i+1;
        else tmp[k++]=q[i++];
    }
    while(i<=mid) tmp[k++]=q[i++];
    while(j<=r) tmp[k++]=q[j++];
    for(int u=l,v=0;u<=r;u++,v++) q[u]=tmp[v];
}
signed main(){
    cin>>n;
    for(int i=0;i<n;i++) cin>>a[i];
    merge_sort(a,0,n-1);
    printf("%lld" ,ans);
}

2.快速排序

核心思想:分治

①确定分界点:x可以取q[l],q[(l+r)>>1],q[r]
②调整范围,把小于x的放在左边,大于x的放在右边(重点)
③递归处理左右两段

方法一:

①开两个额外的数组(好理解,但是很浪费空间)

②q[ l~r ] 枚举区间内的每一个数,然后把每一个数放在相应的数组中

// a->b 表示把a赋值给b
//a指的是小于x的数放在的区间,b是大于x的
int k1=0,k2=0;
int x=q[l];
for(int i=l;i<=r;i++){
    if(q[i]<=x) q[i]->a[k1++];
    if(q[i]->x) q[i]->b[k2++];
}


方法二(常用):

①用两个指针i,j

②当i>=x 时移动j,然后找到符合条件的j,交换i,j,最后处理剩余的


void quick_sort(int q[],int l,int r){
    if(l>=r) return;
    int x=q[l];
    int i=l-1,j=r+1;
    while(i<j){
        do i++; while(q[i]<x);
        do j--; while(q[j]>x);
        if(i<j) swap(q[i],q[j]);
    }
    //如果这个数在自己该在的区间(指的是大于或小于x),就处理下一个,直到处于不应该时的位置时停止,双方进行交换
    quick_sort(q,l,j);
    quick_sort(q,j+1,r);
}

以上两种排序方式一定要三思且用手模拟一遍

归并排序的最经典的应用是求逆序对

快速排序的话可以去看看洛谷P1923(大力推荐,提交时别吸氧)
//千里之行,始于足下

posted @ 2021-08-05 17:30  RevolutionBP  阅读(55)  评论(0编辑  收藏  举报