forked from cmuparlay/pbbslib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
kth_smallest.h
35 lines (32 loc) · 1.17 KB
/
kth_smallest.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#pragma once
#include "sequence_ops.h"
#include "random.h"
namespace pbbs {
template <class Seq, class Compare>
typename Seq::value_type kth_smallest(Seq const &s, size_t k, Compare less,
random r = random()) {
using T = typename Seq::value_type;
size_t n = s.size();
T pivot = s[r[0]%n];
sequence<T> smaller = filter(s, [&] (T a) {return less(a, pivot);});
if (k < smaller.size())
return kth_smallest(smaller, k, less, r.next());
else {
sequence<T> larger = filter(s, [&] (T a) {return less(pivot, a);});
if (k >= n - larger.size())
return kth_smallest(larger, k - n + larger.size(), less, r.next());
else return pivot;
}
}
template <class Seq, class Compare>
typename Seq::value_type approximate_kth_smallest(Seq const &S, size_t k, Compare less, random r = random()) {
// raise exception if empty sequence?
using T = typename Seq::value_type;
size_t n = S.size();
size_t num_samples = n/sqrt(n);
pbbs::sequence<T> samples(num_samples, [&] (size_t i) -> T {
return S[r[i]%n];});
return sample_sort(samples, less)[k * num_samples / n];
//kth_smallest(samples, k * num_samples / n, less);
}
}