快速选择算法

第一章基础算法课

前言

学习思路:课上理解算法思想,课下记忆代码并上手题目,每道题目代码写上3到5遍,重复记忆。

Acwing在线题库

1、快速排序

算法思想:分治策略

时间复杂度:0(nlogn)

算法步骤:

  • 选择分界点x,三种选法,左边点q[l],中间点q[(l+r)/2],右边点q[r]
  • 划分为两个区间,左边区间left所有数<=x,右边区间right所有数>=x
  • 递归排序左区间left和右区间right

上代码:

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){
        while(q[++i]<x);  //相当于do i++; while(q[i]<x);
        while(q[--j]>x);  //相当于do j--; while(q[j]>x);
        if(i<j) swap(i,j);
    }
    quick_sort(q,l,j);
    quick_sort(q,j+1,r);
}
2. 快速选择——求第k个数

题目:给定一个长度为 n 的整数数列,以及一个整数 k,请用快速选择算法求出数列从小到大排序后的第 k个数。

输入格式

第一行包含两个整数 n 和 k。

第二行包含 n 个整数(所有整数均在 1∼1091∼109 范围内),表示整数数列。

输出格式

输出一个整数,表示数列的第 k 小数。

对于求第k个数的问题,我们很容易想到使用排序法解决,但是排序算法的时间复杂度最小也是0(nlogn),那么怎样才能更加优雅高效的解决第k小数的问题呢,这就不得不要说一说快速选择算法了。

快速选择算法是基于快速排序算法的变形,它的总体思路和快速排序是一样的,选择一个元素作为基准元素,将小于基准的元素和大于基准的元素分别放在左右两边,不同的是,快速选择算法每次不用递归访问左右两边,而是递归进入其中一边继续进行查找,这就将平均时间复杂度从O(nlogn)降到了O(n)。

算法步骤:

  • 同样是选择分界点x,三种选法q[l],q[(l+r)/2],q[r]
  • 划分为两个区间left和right,left中所有元素都小于x,right中所有元素都大于x,记录left和right的区间长度分别为Sl和Sr
  • 若k小于等于Sl,则递归访问左区间left;若k大于Sl,则递归访问右区间Sr,此时k为右区间right中第k-Sl小的数

快速选择代码:

quick_select(q[],int l,int r,int k){  //寻找第k小的数
    int x = q[l];
    int i = l-1,j = r+1;
    
    if(l == r) return q[l];
    while(i < j){
        while(q[++ i] < x);
        while(q[-- j] > x);
        if(i < j) swap(q[i],q[j]);
    }
    int sl = j - l + 1;
    if(k <= s1) return quick_select(q,l,j,k);
    else return quick_select(q,j+1,r,k-s1);
}

啊啊啊,调试了好久才通过,代码太生疏了

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值