复盘笔记-算法基础课-1

排序算法

算法思想-分治。确认分界点,不断调整区间,使得分界点的左边全部小于分界点,右边全部大于分界点,递归处理左右两段区间直至全部有序。

使用两个指针不断向中间位置(实际上是分界点)逼近,知直到确定分界点的位置。

模板:

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

    int i = l - 1, j = r + 1, x = q[(l + r ) /2];
    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, l, i-1);模拟后可以发现i和j的位置,每次能确定一个数的位置
    quick_sort(q, j + 1, r);  //  quick_sort(q, i, r);

}

常规代码:

void Quick_Sort(int a[], int low, int high) {
    if (low > high)
        return;
    int pivot = a[low];
    int i = low;
    int j = high;
    while (i != j) {//不断交换左边比枢纽大的值和右边比枢纽小的值,循环结束后i和j的值应当为i>=j
        while (a[j] >= pivot && j > i)
            j--;
        while (a[i] <= pivot && j > i)
            i++;
        if (j > i) {
            int t = a[i];
            a[i] = a[j];
            a[j] = t;
        }
    }
    a[low] = a[i];//i指向的为比枢纽小的值,此时循环结束后i左边应当都是比枢纽小的值,交换位置后可确定枢纽排序后的位置
    a[i] = pivot;
    Quick_Sort(a, low, i - 1);
    Quick_Sort(a, i + 1, high);
}

归并算法

算法思想:分治。确定分界点,递归排序左边和右边,得到两个有序的小区间,归并整个数组。难点在如何合并两个已经有序的数列。

双路归并,合二为一。

模板:

void mergesort(int a[], int low, int high) {
    if (low >= high) return;
    int mid = (low + high) / 2;
    mergesort(a, low, mid);
    mergesort(a, mid + 1, high);
    int temp[N];
    int k = 0, i = low, j = mid+1;
    while (i <= mid && j <= high) {
        if (a[i] <= a[j])
            temp[k++] = a[i++];

        else
            temp[k++] = a[j++];
    }
    while (i <= mid) temp[k++] = a[i++];
    while (j <= high) temp[k++] = a[j++];
    for (int i = low, j = 0; i <= high;) a[i++] = temp[j++];
}

二分查找

算法思想:二分查找复合某个条件的元素值

二分本质是用来查找满足某种性质的边界点
在给定区间内,能找到某种性质使得区间分为两部分,一部分满足,另外一部分不满足这种性质,
二分就可以用来寻找这个性质的边界:满足某种性质的第一个元素;或者是满足某种性质的最后一个元素。
从而有两个不同模板。
注意二分法一定能找到满足某种性质的边界点,但它不一定是你要找的目标,目标不一定在区间内
先写check函数,如何根据check函数更新区间,再判断选用哪个模板
主要是边界问题

模板:

bool check(int x) {/* ... */} // 检查x是否满足某种性质
// 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用:
int bsearch_1(int l, int r)
{
    while (l < r)
    {
        int mid = l + r >> 1;
        if (check(mid)) r = mid;    // check()判断mid是否满足性质
        else l = mid + 1;
    }
    return l;
}
// 区间[l, r]被划分成[l, mid - 1]和[mid, r]时使用:
int bsearch_2(int l, int r)
{
    while (l < r)
    {
        int mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    return l;
}

浮点数二分

模板

bool check(double x) {/* ... */} // 检查x是否满足某种性质

double bsearch_3(double l, double r)
{
    const double eps = 1e-6;   // eps 表示精度,取决于题目对精度的要求
    while (r - l > eps)
    {
        double mid = (l + r) / 2;
        if (check(mid)) r = mid;
        else l = mid;
    }
    return l;
}

也可以直接循环一百次,不用while循环

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值