-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy patharrayqueue.rs
86 lines (77 loc) · 2.16 KB
/
arrayqueue.rs
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use chapter01::interface::Queue;
#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Array<T> {
a: Box<[Option<T>]>,
j: usize,
n: usize,
}
impl<T> Array<T> {
pub fn length(&self) -> usize {
self.a.len()
}
pub fn new() -> Self {
Self::with_length(1)
}
pub fn with_length(capacity: usize) -> Self {
Self {
a: Self::allocate_in_heap(capacity),
j: 0,
n: 0,
}
}
fn allocate_in_heap(size: usize) -> Box<[Option<T>]> {
std::iter::repeat_with(Default::default)
.take(size)
.collect::<Vec<_>>()
.into_boxed_slice()
}
fn resize(&mut self) {
let new_a = Self::allocate_in_heap(std::cmp::max(self.n * 2, 1));
let mut old_a = std::mem::replace(&mut self.a, new_a);
for k in 0..self.n {
self.a[k] = old_a[(self.j + k) % old_a.len()].take();
}
self.j = 0;
}
}
impl<T> Queue<T> for Array<T> {
fn add(&mut self, value: T) {
if self.n + 1 >= self.length() {
self.resize();
}
self.a[(self.j + self.n) % self.length()] = Some(value);
self.n += 1;
}
fn remove(&mut self) -> Option<T> {
let x = self.a[self.j].take();
self.j = (self.j + 1) % self.length();
self.n -= 1;
if self.length() >= 3 * self.n {
self.resize();
}
x
}
}
#[cfg(test)]
mod test {
use super::Array;
use chapter01::interface::Queue;
#[test]
fn test_arrayqueue() {
let mut array_queue: Array<char> = Array::new();
for elem in "aaabc".chars() {
array_queue.add(elem);
}
assert_eq!(array_queue.remove(), Some('a'));
assert_eq!(array_queue.remove(), Some('a'));
array_queue.add('d');
array_queue.add('e');
assert_eq!(array_queue.remove(), Some('a'));
array_queue.add('f');
array_queue.add('g');
assert_eq!(array_queue.length(), 10);
array_queue.add('h');
assert_eq!(array_queue.remove(), Some('b'));
println!("\nArrayQueue = {:?}\n", array_queue);
}
}