算法导论中的顺序统计学示范代码

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
namespace select {
/** * 使用快速排序的思想完成选择 **/
int divide(vector<int>& in, int beg, int end, int pivot) {
    if (beg >= end) return -1;
    int b = beg, e = end - 1;
    while (b < e) {
        while(b < e && in[e] >= pivot) e--;
        while(b < e && in[b] < pivot) b++;
        swap(in[b], in[e]);
    }
    return b;
}
int quick_select(vector<int>& in, int k) {
    int beg = 0, end = in.size();
    while (k >= 0 && beg < end) {
        int mid = divide(in, beg, end, in[beg]);
        if (mid - beg == k) return in[mid];
        else if (mid - beg < k) {
            k -= (mid - beg + 1);//思维惰性,导致的错误,懒害死人的,细节决定成败
            beg = mid + 1;
        } else {
            end = mid;
        }
    }
    return 0;
}
/** * 使用分组中位数的思想完成选择 **/
void insert_sert_seg(vector<int>& in, int beg, int end) {
    for (int i = beg + 1; i < end; ++i) {
        int tmp = in[i];
        int j = i - 1;
        while(j >= 0 && in[j] > tmp) {
            in[j + 1] = in[j];
            j--;
        }
        in[j + 1] = tmp;
    }
}
int on_select(vector<int>& in, int k, int beg, int end) {
    if (beg + 1 == end) return in[beg];
    vector<int> tmp;
    for (int i = beg; i < end; i += 5) {
        int b = i * 5;
        int e = min((i + 1) * 5, end);
        insert_sert_seg(in, b, e);
        tmp.push_back(in[(b + e) / 2]);
    }
    int mid_val = on_select(tmp, tmp.size() / 2, 0, (int)tmp.size());

    int mid = divide(in, beg, end, mid_val);
    if (mid - beg == k) return in[mid];
    else if (mid - beg < k) {
        k -= (mid - beg + 1);//思维惰性,导致的错误,懒害死人的,细节决定成败
        beg = mid + 1;
    } else {
        end = mid;
    }
    return on_select(in, k, beg, end);
}
int lineartime_select(vector<int>& in, int k) {
    k = k % (int) in.size();
    return on_select(in, k, 0, (int)in.size());
}
};

int main() {
    vector<int> data;
    int k;
    int n;
    cin>>n;
    for (int i = 1; i <= n; ++i) {
        int tmp;
        cin>>tmp;
        data.push_back(tmp);
    }
    cin>>k;
    //int ret = select::quick_select(data, k);
    int ret = select::lineartime_select(data, k);
    cout<<ret<<endl;
    return 0;
}
点赞