Skip to content

Commit d8da439

Browse files
supermacroegonSchiele
authored andcommitted
implement recursive binary serach in rust (egonSchiele#93)
1 parent 9dc7611 commit d8da439

File tree

3 files changed

+113
-0
lines changed

3 files changed

+113
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[[package]]
2+
name = "binary-search"
3+
version = "0.1.0"
4+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "binary-search"
3+
version = "0.1.0"
4+
authors = ["giorgiodelgado <hi@gdelgado.ca>"]
5+
6+
[dependencies]
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// to run tests, you must have rust and cargo installed
2+
// then run `cargo test`
3+
4+
use std::cmp;
5+
6+
// assumes that the slice is already sorted
7+
fn binary_search<T: cmp::PartialOrd>(lst: &[T], item: T) -> Option<usize> {
8+
let mid = ((lst.len() / 2) as f32).ceil() as usize;
9+
10+
match lst.get(mid) {
11+
None => None,
12+
Some(val) => {
13+
if *val == item {
14+
Some(mid)
15+
} else if *val > item {
16+
let sublist = &lst[..mid];
17+
binary_search(sublist, item)
18+
} else {
19+
let sublist = &lst[(mid + 1)..];
20+
// mapping is necessary when the item is
21+
// to the right of the middle since indices on the
22+
// sublist are erased and being at 0, 1, 2, 3, ... etc
23+
binary_search(sublist, item).map(|pos| pos + mid + 1)
24+
}
25+
},
26+
}
27+
}
28+
29+
fn main() {
30+
let num_slice = &[2, 4, 5, 12, 15, 30, 32, 33, 34, 40, 45, 51, 55, 57, 60, 66, 70, 71, 90, 99, 100];
31+
32+
let result = binary_search(num_slice, 70);
33+
34+
println!("Result: {:?}", result);
35+
}
36+
37+
38+
#[cfg(test)]
39+
mod test {
40+
use super::binary_search;
41+
42+
#[test]
43+
fn finds_number_near_end_of_list() {
44+
let num_slice = &[2, 4, 5, 12, 15, 30, 32, 33, 34, 40, 45, 51, 55, 57, 60, 66, 70, 71, 90, 99, 100];
45+
46+
assert_eq!(binary_search(num_slice, 70), Some(16));
47+
}
48+
49+
#[test]
50+
fn finds_number_near_start_of_list() {
51+
let num_slice = &[2, 4, 5, 12, 15, 30, 32, 33, 34, 40, 45, 51, 55, 57, 60, 66, 70, 71, 90, 99, 100];
52+
53+
assert_eq!(binary_search(num_slice, 5), Some(2));
54+
}
55+
56+
#[test]
57+
fn returns_none_for_numbers() {
58+
let num_slice = &[2, 4, 5, 12, 15, 30, 32, 33, 34, 40, 45, 51, 55, 57, 60, 66, 70, 71, 90, 99, 100];
59+
60+
assert_eq!(binary_search(num_slice, 1), None);
61+
}
62+
63+
#[test]
64+
fn finds_char() {
65+
let char_slice = &[
66+
'a',
67+
'b',
68+
'c',
69+
'd',
70+
'e',
71+
'f',
72+
'g',
73+
'h',
74+
'i',
75+
'j',
76+
'k',
77+
'l',
78+
'm',
79+
'n',
80+
'o',
81+
'p',
82+
'q',
83+
'r',
84+
's',
85+
't',
86+
'u',
87+
'v',
88+
'w',
89+
'x',
90+
'y',
91+
'z',
92+
];
93+
94+
assert_eq!(binary_search(char_slice, 'l'), Some(11));
95+
}
96+
97+
#[test]
98+
fn returns_none_for_chars() {
99+
let char_slice = &['a', 'b', 'c'];
100+
101+
assert_eq!(binary_search(char_slice, 'l'), None);
102+
}
103+
}

0 commit comments

Comments
 (0)