[_附背诵模板_]基础算法

目录

快速排序模板

归并排序模板

#include中的Sort函数使用用法

整数二分模板

浮点数二分模板

高精度加法模板

高精度减法模板

高精度乘低精度模板

高精度除法模板

一维前缀和模板

二维前缀和模板

一维差分模板

二维差分模板


快速排序模板

快速排序是基于分治思想的常用于算法竞赛的排序算法

步骤:

1、确定分界点 :q[L]     q[(L+R)/2]     q[R]

2、💖调整区间范围:使得小于等于x的在一边,大于等于x的在另一边

3、递归处理左右两边

 重点在于,如何调整区间范围,先说一种很简单的、笨拙的方式(一般不采用):

  1. 先定义两个数组a[ ]、b[ ],分别装小于等于x、大于等于x的数据
  2. 遍历q数组,将符合条件的数据分别放在a数组和b数组中
  3. a数组和b数组,拼接即又组成新的q数组
  4. 继续递归...

最常用的方式是如下双指针的用法,需要背记模板

调整区间范围的经典步骤:

  1. 选定一个分界点的数x,即:小于x的数要等会放在左边,大于x的数要放在右边                                                                           (一般我们选分界点是数组中点,当然也可以有其他选法)
  2. 定义两个指针i、j分别指向起始位置得前一位惯用技巧)和末尾位置后一个位置
  3.  i++,然后判断 i 指向的数是否小于 x。如果 i 指向的数小于x,那么 i 继续往后走,即:i++。否则,此时i停住                                       j--,然后判断 j 指向的数是都大于 x。如果 j 指向的数大于x,那么 j 继续往前走,即:j--。否则,j  停住                                   (由于此时i,j都停住,因为他们指向的数都不符合条件【左边放较小的数,右边放较大的数】,所以此时i、j指向的数交换)
  4. swap(),交换i、j分别指向得数
  5. 继续i++,j--执行上述判断..................

模板

void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;

    int i = l - 1, j = r + 1, x = q[l + 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]);
    }
    quick_sort(q, l, j);
    quick_sort(q, j + 1, r);
}

整体应用:

#include<iostream>

using namespace std;

const int N = 1e6 + 10;

int n;
int q[N];

void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;

    int i = l - 1, j = r + 1, x = q[l + 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]);
    }
    quick_sort(q, l, j);
    quick_sort(q, j + 1, r);
}

int main()
{
    scanf("%d", &n);
    for (int i = 0; i < n; i++) scanf("%d", &q[i]);

    quick_sort(q, 0, n - 1);

    for (int i = 0; i < n; i++) printf("%d ", q[i]);

    return 0;
}

归并排序模板

归并排序也是基于分治思想的常用于算法竞赛的排序算法

步骤:

1、确定分界点 :确定分界点:mid = (L + R)/2

2、递归排序leftright

3、归并----合二为一   (重点

 “   合二为一   ”的过程步骤:

由于递归后的左半边的数组和右半边的数组都是有序的。

  1. 分别定义两个指针,指向两个数组起始位置的数据
  2. i  与  j  比较大小,较小的放在res数组中。然后较小的继续往后移动,继续与刚刚的另一个指针所指的数据比较                                            (注意:一个数组已经结束,另一个数组还有剩余元素,则直接将剩余元素放在res数组中即可

模板

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 k = 0, i = l, j = mid + 1;//注意: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 (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j];
}

整体应用:

#include<iostream>

using namespace std;

const int N = 1e6 + 10;

int n;
int q[N], tmp[N];

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 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++];

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值