1
1
// Heap data structure
2
2
// Takes a closure as a comparator to allow for min-heap, max-heap, and works with custom key functions
3
3
4
- use std:: cmp:: Ord ;
5
- use std:: default:: Default ;
4
+ use std:: { cmp:: Ord , slice:: Iter } ;
6
5
7
- pub struct Heap < T >
8
- where
9
- T : Default ,
10
- {
11
- count : usize ,
6
+ pub struct Heap < T > {
12
7
items : Vec < T > ,
13
8
comparator : fn ( & T , & T ) -> bool ,
14
9
}
15
10
16
- impl < T > Heap < T >
17
- where
18
- T : Default ,
19
- {
11
+ impl < T > Heap < T > {
20
12
pub fn new ( comparator : fn ( & T , & T ) -> bool ) -> Self {
21
13
Self {
22
- count : 0 ,
23
14
// Add a default in the first spot to offset indexes
24
15
// for the parent/child math to work out.
25
16
// Vecs have to have all the same type so using Default
26
17
// is a way to add an unused item.
27
- items : vec ! [ T :: default ( ) ] ,
18
+ items : vec ! [ ] ,
28
19
comparator,
29
20
}
30
21
}
31
22
32
23
pub fn len ( & self ) -> usize {
33
- self . count
24
+ self . items . len ( )
34
25
}
35
26
36
27
pub fn is_empty ( & self ) -> bool {
37
28
self . len ( ) == 0
38
29
}
39
30
40
31
pub fn add ( & mut self , value : T ) {
41
- self . count += 1 ;
42
32
self . items . push ( value) ;
43
33
44
34
// Heapify Up
45
- let mut idx = self . count ;
46
- while self . parent_idx ( idx) > 0 {
47
- let pdx = self . parent_idx ( idx) ;
35
+ let mut idx = self . len ( ) - 1 ;
36
+ while let Some ( pdx) = self . parent_idx ( idx) {
48
37
if ( self . comparator ) ( & self . items [ idx] , & self . items [ pdx] ) {
49
38
self . items . swap ( idx, pdx) ;
50
39
}
51
40
idx = pdx;
52
41
}
53
42
}
54
43
55
- fn parent_idx ( & self , idx : usize ) -> usize {
56
- idx / 2
44
+ pub fn pop ( & mut self ) -> Option < T > {
45
+ if self . is_empty ( ) {
46
+ return None ;
47
+ }
48
+ // This feels like a function built for heap impl :)
49
+ // Removes an item at an index and fills in with the last item
50
+ // of the Vec
51
+ let next = Some ( self . items . swap_remove ( 0 ) ) ;
52
+
53
+ if !self . is_empty ( ) {
54
+ // Heapify Down
55
+ let mut idx = 0 ;
56
+ while self . children_present ( idx) {
57
+ let cdx = {
58
+ if self . right_child_idx ( idx) >= self . len ( ) {
59
+ self . left_child_idx ( idx)
60
+ } else {
61
+ let ldx = self . left_child_idx ( idx) ;
62
+ let rdx = self . right_child_idx ( idx) ;
63
+ if ( self . comparator ) ( & self . items [ ldx] , & self . items [ rdx] ) {
64
+ ldx
65
+ } else {
66
+ rdx
67
+ }
68
+ }
69
+ } ;
70
+ if !( self . comparator ) ( & self . items [ idx] , & self . items [ cdx] ) {
71
+ self . items . swap ( idx, cdx) ;
72
+ }
73
+ idx = cdx;
74
+ }
75
+ }
76
+
77
+ next
78
+ }
79
+
80
+ pub fn iter ( & self ) -> Iter < ' _ , T > {
81
+ self . items . iter ( )
82
+ }
83
+
84
+ fn parent_idx ( & self , idx : usize ) -> Option < usize > {
85
+ if idx > 0 {
86
+ Some ( ( idx - 1 ) / 2 )
87
+ } else {
88
+ None
89
+ }
57
90
}
58
91
59
92
fn children_present ( & self , idx : usize ) -> bool {
60
- self . left_child_idx ( idx) <= self . count
93
+ self . left_child_idx ( idx) <= ( self . len ( ) - 1 )
61
94
}
62
95
63
96
fn left_child_idx ( & self , idx : usize ) -> usize {
64
- idx * 2
97
+ idx * 2 + 1
65
98
}
66
99
67
100
fn right_child_idx ( & self , idx : usize ) -> usize {
68
101
self . left_child_idx ( idx) + 1
69
102
}
70
-
71
- fn smallest_child_idx ( & self , idx : usize ) -> usize {
72
- if self . right_child_idx ( idx) > self . count {
73
- self . left_child_idx ( idx)
74
- } else {
75
- let ldx = self . left_child_idx ( idx) ;
76
- let rdx = self . right_child_idx ( idx) ;
77
- if ( self . comparator ) ( & self . items [ ldx] , & self . items [ rdx] ) {
78
- ldx
79
- } else {
80
- rdx
81
- }
82
- }
83
- }
84
103
}
85
104
86
105
impl < T > Heap < T >
87
106
where
88
- T : Default + Ord ,
107
+ T : Ord ,
89
108
{
90
109
/// Create a new MinHeap
91
110
pub fn new_min ( ) -> Heap < T > {
@@ -98,45 +117,13 @@ where
98
117
}
99
118
}
100
119
101
- impl < T > Iterator for Heap < T >
102
- where
103
- T : Default ,
104
- {
105
- type Item = T ;
106
-
107
- fn next ( & mut self ) -> Option < T > {
108
- if self . count == 0 {
109
- return None ;
110
- }
111
- // This feels like a function built for heap impl :)
112
- // Removes an item at an index and fills in with the last item
113
- // of the Vec
114
- let next = Some ( self . items . swap_remove ( 1 ) ) ;
115
- self . count -= 1 ;
116
-
117
- if self . count > 0 {
118
- // Heapify Down
119
- let mut idx = 1 ;
120
- while self . children_present ( idx) {
121
- let cdx = self . smallest_child_idx ( idx) ;
122
- if !( self . comparator ) ( & self . items [ idx] , & self . items [ cdx] ) {
123
- self . items . swap ( idx, cdx) ;
124
- }
125
- idx = cdx;
126
- }
127
- }
128
-
129
- next
130
- }
131
- }
132
-
133
120
#[ cfg( test) ]
134
121
mod tests {
135
122
use super :: * ;
136
123
#[ test]
137
124
fn test_empty_heap ( ) {
138
125
let mut heap: Heap < i32 > = Heap :: new_max ( ) ;
139
- assert_eq ! ( heap. next ( ) , None ) ;
126
+ assert_eq ! ( heap. pop ( ) , None ) ;
140
127
}
141
128
142
129
#[ test]
@@ -147,11 +134,11 @@ mod tests {
147
134
heap. add ( 9 ) ;
148
135
heap. add ( 11 ) ;
149
136
assert_eq ! ( heap. len( ) , 4 ) ;
150
- assert_eq ! ( heap. next ( ) , Some ( 2 ) ) ;
151
- assert_eq ! ( heap. next ( ) , Some ( 4 ) ) ;
152
- assert_eq ! ( heap. next ( ) , Some ( 9 ) ) ;
137
+ assert_eq ! ( heap. pop ( ) , Some ( 2 ) ) ;
138
+ assert_eq ! ( heap. pop ( ) , Some ( 4 ) ) ;
139
+ assert_eq ! ( heap. pop ( ) , Some ( 9 ) ) ;
153
140
heap. add ( 1 ) ;
154
- assert_eq ! ( heap. next ( ) , Some ( 1 ) ) ;
141
+ assert_eq ! ( heap. pop ( ) , Some ( 1 ) ) ;
155
142
}
156
143
157
144
#[ test]
@@ -162,14 +149,13 @@ mod tests {
162
149
heap. add ( 9 ) ;
163
150
heap. add ( 11 ) ;
164
151
assert_eq ! ( heap. len( ) , 4 ) ;
165
- assert_eq ! ( heap. next ( ) , Some ( 11 ) ) ;
166
- assert_eq ! ( heap. next ( ) , Some ( 9 ) ) ;
167
- assert_eq ! ( heap. next ( ) , Some ( 4 ) ) ;
152
+ assert_eq ! ( heap. pop ( ) , Some ( 11 ) ) ;
153
+ assert_eq ! ( heap. pop ( ) , Some ( 9 ) ) ;
154
+ assert_eq ! ( heap. pop ( ) , Some ( 4 ) ) ;
168
155
heap. add ( 1 ) ;
169
- assert_eq ! ( heap. next ( ) , Some ( 2 ) ) ;
156
+ assert_eq ! ( heap. pop ( ) , Some ( 2 ) ) ;
170
157
}
171
158
172
- #[ derive( Default ) ]
173
159
struct Point ( /* x */ i32 , /* y */ i32 ) ;
174
160
175
161
#[ test]
@@ -179,9 +165,34 @@ mod tests {
179
165
heap. add ( Point ( 3 , 10 ) ) ;
180
166
heap. add ( Point ( -2 , 4 ) ) ;
181
167
assert_eq ! ( heap. len( ) , 3 ) ;
182
- assert_eq ! ( heap. next ( ) . unwrap( ) . 0 , -2 ) ;
183
- assert_eq ! ( heap. next ( ) . unwrap( ) . 0 , 1 ) ;
168
+ assert_eq ! ( heap. pop ( ) . unwrap( ) . 0 , -2 ) ;
169
+ assert_eq ! ( heap. pop ( ) . unwrap( ) . 0 , 1 ) ;
184
170
heap. add ( Point ( 50 , 34 ) ) ;
185
- assert_eq ! ( heap. next( ) . unwrap( ) . 0 , 3 ) ;
171
+ assert_eq ! ( heap. pop( ) . unwrap( ) . 0 , 3 ) ;
172
+ }
173
+
174
+ #[ test]
175
+ fn test_iter_heap ( ) {
176
+ let mut heap = Heap :: new_min ( ) ;
177
+ heap. add ( 4 ) ;
178
+ heap. add ( 2 ) ;
179
+ heap. add ( 9 ) ;
180
+ heap. add ( 11 ) ;
181
+
182
+ // test iterator, which is not in order except the first one.
183
+ let mut iter = heap. iter ( ) ;
184
+ assert_eq ! ( iter. next( ) , Some ( & 2 ) ) ;
185
+ assert_ne ! ( iter. next( ) , None ) ;
186
+ assert_ne ! ( iter. next( ) , None ) ;
187
+ assert_ne ! ( iter. next( ) , None ) ;
188
+ assert_eq ! ( iter. next( ) , None ) ;
189
+
190
+ // test the heap after run iterator.
191
+ assert_eq ! ( heap. len( ) , 4 ) ;
192
+ assert_eq ! ( heap. pop( ) , Some ( 2 ) ) ;
193
+ assert_eq ! ( heap. pop( ) , Some ( 4 ) ) ;
194
+ assert_eq ! ( heap. pop( ) , Some ( 9 ) ) ;
195
+ assert_eq ! ( heap. pop( ) , Some ( 11 ) ) ;
196
+ assert_eq ! ( heap. pop( ) , None ) ;
186
197
}
187
198
}
0 commit comments