forked from cmuparlay/pbbslib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
binary_search.h
51 lines (44 loc) · 1.41 KB
/
binary_search.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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#pragma once
#include <stddef.h>
namespace pbbs {
// the following parameter can be tuned
constexpr const size_t _binary_search_base = 16;
template <typename Seq, typename F>
size_t linear_search(Seq const &I, typename Seq::value_type const &v,
const F& less) {
for (size_t i = 0; i < I.size(); i++)
if (!less(I[i],v)) return i;
return I.size();
}
// return index to first key greater or equal to v
template <typename Seq, typename F>
size_t binary_search(Seq const &I, typename Seq::value_type const &v,
const F& less) {
size_t start = 0;
size_t end = I.size();
while (end-start > _binary_search_base) {
size_t mid = (end+start)/2;
if (!less(I[mid],v)) end = mid;
else start = mid + 1;
}
return start + linear_search(I.slice(start,end),v,less);
}
template <typename Seq, typename F>
size_t linear_search(Seq const &I, const F& less) {
for (size_t i = 0; i < I.size(); i++)
if (!less(I[i])) return i;
return I.size();
}
// return index to first key where less is false
template <typename Seq, typename F>
size_t binary_search(Seq const &I, const F& less) {
size_t start = 0;
size_t end = I.size();
while (end-start > _binary_search_base) {
size_t mid = (end+start)/2;
if (!less(I[mid])) end = mid;
else start = mid + 1;
}
return start + linear_search(I.slice(start,end),less);
}
}