Acwing 快排 归并 整理笔记

简介: Acwing 快排 归并 整理笔记

20f5b6f1ee93439a99cd254fa4d77a5c.png

快速排序:

快排板子分治思想

1.确定分界点(x = a[l+r>>1]),这么做是为了避免有序的情况下,子问题规模依旧较大的问题(如果有序且分界点取在首个,那么数组被分为长度1和n-1)

2.调整区间,使得第一个区间<=x,第二个区间>=x;

3.递归两个区间

#include <iostream>
#include <cstdio>
using namespace std;
const int N = 1e5+10;
int a[N];
void quicksort(int l,int r,int a[])
{
    if (l>=r) return;
    int i = l-1,j = r+1,x = a[i+j>>1];
    while (i<j)
    {
        do i++;while (a[i]<x);
        do j--;while (a[j]>x);
        if (i<j) swap(a[i],a[j]);
    }
    quicksort(l,j,a);
    quicksort(j+1,r,a);
}
int main()
{   
    int n;
    scanf("%d",&n);
    for (int i = 0;i<n;i++) scanf("%d",&a[i]);
    quicksort(0,n-1,a);
    for (int i = 0;i<n;i++) printf("%d ",a[i]);
    return 0;
}

归并排序


20ab39b2b4f04a1f8dd3705810a065ad.png


1:确定分界点

2:递归

3:归并merge(注意可能一条链子输完了另一条还没有输完的情况)

归并板子

#include <iostream>
#include <cstdio>
using namespace std;
const int N = 1e5+10;
int tmp[N];//临时容器
int a[N];
void mergesort(int l,int r,int a[])
{
    if (l>=r) return ;
    int mid = l+r>>1;//划分区间
    mergesort(l,mid,a);
    mergesort(mid+1,r,a);//递归排序
    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 (int i = l,j = 0;j<k;j++,i++) a[i] = tmp[j];//复制到到原数组
}
int main()
{   
    int n;
    scanf("%d",&n);
    for (int i = 0;i<n;i++) scanf("%d",&a[i]);
    mergesort(0,n-1,a);
    for (int i = 0;i<n;i++) printf("%d ",a[i]);
    return 0;
}

经典例题:逆序对的数量:acwing788

给定一个长度为 n 的整数数列,请你计算数列中的逆序对的数量。

输入样例:

1. 6
2. 2 3 4 5 6 1

输出样例:

5

逆序对分成三块,前两块ans加上函数自身的递归,第三块先排序再累加;

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;
const LL N = 1e5+10;
LL a[N],tmp[N];
LL mergesort(LL l,LL r,LL a[])
{   
    if (l>=r) return 0;
    LL mid = l+r>>1;
    LL ans = 0;
    ans+=mergesort(l,mid,a)+mergesort(mid+1,r,a);
    LL 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++];
            ans += mid-i+1;
        }
    }
    while (i<=mid) tmp[k++] = a[i++];
    while (j<=r)   tmp[k++] = a[j++];
    for (LL i = 0,j = l;i<k;i++,j++)  a[j] = tmp[i];
    return ans;
}
int main()
{
    LL n;
    scanf("%ld",&n);
    for (int i = 0;i<n;i++) scanf("%ld",&a[i]);
    LL ans = mergesort(0,n-1,a);
    printf("%ld",ans);
    return 0;
}

24839e48d8354f78a2d6d4b36151c074.png


1cd7edfae477414eb259b78ee9896f5d.png


相关文章
|
4月前
|
算法
双指针算法(acwing)疑难讲解
双指针算法(acwing)疑难讲解
34 0
|
3月前
|
机器学习/深度学习 搜索推荐 算法
【洛谷 P1177】【模板】快速排序 题解(快速排序+指针)
**快速排序模板题解** - **任务**:对输入的N个整数进行排序。 - **算法**:使用快速排序,避免使用C++的STL`sort`。 - **输入**:一行包含N(N≤10^5),第二行是N个不超过10^9的整数。 - **输出**:排序后的整数序列,空格分隔。 - **样例**:输入`5 4 2 4 5 1`,输出`1 2 4 4 5`。 - **提示**:20%的数据,N≤10^3;所有数据,N≤10^5。 - **代码**:定义`partition`函数划分数组,主函数`main`读取数据,调用`quickSort`排序,然后打印结果。
14 0
|
算法
数据结构实验十五 插入排序
数据结构实验十五 插入排序
62 0
|
算法 Java 测试技术
Leetcode刷题笔记:二分查找算法
LeetCode 对于数组查询算法之一的二分查找算法的简单认识。
95 0
|
算法 搜索推荐
算法笔记(二)——快排,归并算法(做成模板题)
算法笔记(二)——快排,归并算法(做成模板题)
算法笔记(二)——快排,归并算法(做成模板题)
|
算法 搜索推荐
【数据结构与算法】:交换排序之快速排序(手绘图解+LeetCode原题)
快速排序是交换排序的一种,本质上快速排序就是采用“分而治之”的策略(分治法),将问题规模减小,再而对问题分别进行处理的排序算法。
117 0
【数据结构与算法】:交换排序之快速排序(手绘图解+LeetCode原题)
|
算法 Java C++
【LeetCode-算法入门】第1天:二分查找
【LeetCode-算法入门】第1天:二分查找
141 0
【LeetCode-算法入门】第1天:二分查找
|
算法 搜索推荐
【算法笔记】关于快排
【算法笔记】关于快排
179 0