算法基础课:第一章 基础算法(一)

本文深入讲解了快速排序和归并排序两种高效的排序算法。快速排序通过分治策略,选取分界点进行数据划分,递归处理左右子序列;归并排序则通过递归将序列分为更小的部分,再合并已排序的子序列。文章提供了详细的算法步骤和模板代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

排序

快速排序

在q[L:R]中

  1. 确定分界点:q[L]  q[(L+R)/2]  q[R]  随机
  2. 调整区间:使得分界点x的左侧,数值皆<=x,右侧皆>=x(i j两者从左、右两个方向分别寻找不符合的数字,然后两者交换,直至相遇)
  3. 递归处理左右两段

模板代码如下(一定记牢):

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);
}

785. 快速排序 

786. 第k个数

归并排序

在q[L:R]中

  1. 确定分界点:mid=L+R>>1
  2. 递归排序左右两区间
  3. 归并——合二为一(双指针,取两个区间中最小值,放入结果数组中)
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 ++ ];

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

787. 归并排序 

788. 逆序对的数量

二分法

整数

本质是整个区间在左或右半部分不满足某种性质,而另一半部分满足该性质,整数二分即找到分界点

int binary_search(int nums[], int n, int target) {
    int left = 0, right = n - 1; 
    while(left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] < target) {
            left = mid + 1;
        } else if (nums[mid] > target) {
            right = mid - 1; 
        } else if(nums[mid] == target) {
            // 直接返回
            return mid;
        }
    }
    // 直接返回
    return -1;
}

int left_bound(int nums[], int n, int target) {
    int left = 0, right = n - 1;
    while (left <= right) {
        int mid = left + (right - left >> 1);
        if (nums[mid] < target) left = mid + 1;
        else right = mid - 1;
    }
    // 最后要检查 left 越界的情况
    if (left >= n || nums[left] != target) return -1;
    return left;
}


int right_bound(int nums[], int n, int target) {
    int left = 0, right = n - 1;
    while (left <= right) {
        int mid = left + (right - left >> 1);
        if (nums[mid] > target) right = mid - 1;
        else left = mid + 1;
    }
    // 最后要检查 right 越界的情况
    if (right < 0 || nums[right] != target) return -1;
    return right;
}

789. 数的范围 

浮点数

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;
}

790. 数的三次方根 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值