算法设计与分析——求无序序列中第k小的数(类快排思想)

#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <cstdio>
#include <string>
#include <stack>
#include <set>
#define IOS ios::sync_with_stdio(false)
using namespace std;
typedef long long ll;
const int maxn=1000;
//二分法在无序序列中找到第k小的数
int find_k(int l,int r,int a[],int k){
    if(l==r)return a[l];
    int mid=a[l];//将访问区间的第一个作为分界标准值
    int pre=l,rear=r+1;
    //将所有小于mid的放到mid左边,大于mid的放到mid右边,两遍都有可能存在等于mid的
    while(pre<rear){
        while(pre<r&&a[++pre]<mid);//从左边开始找不小于mid的数
        while(a[--rear]>mid);//从右边找不大于mid的数
        if(pre<rear)//如果没有到达分界处就交换
            swap(a[pre],a[rear]);
    }
    a[l]=a[rear];
    a[rear]=mid;//将标准值放到分解处(a[rear]保证了小于mid所以可以交换)
    if(k==rear)return a[rear];//如果rear的值正好是k,根据搜索的原理,第k小的数肯定等于a[rear];
    //根据k所在区间搜索左或右两个区间
    if(k<rear){
        return find_k(l,rear-1,a,k);
    }
    else{
        return find_k(rear+1,r,a,k);
    }
}
int main()
{
    IOS;
    int n,k;
    int a[maxn];
    cout<<"序列元素的个数:";
    cin>>n;
    cout<<"第k小数:k=";
    while(cin>>k){
        if(k<1||k>n){
            cout<<"输入的k应该在区间[1:n]范围,请重新输入"<<endl;
            cout<<"k=";
        }
        else break;
    }
    cout<<"输入"<<n<<"个元素值(空格间隔):";
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    int ans=find_k(1,n,a,k);//求a[1:n]内第k小的数
    cout<<"ans="<<ans<<endl;
    getchar();
    getchar();
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值