1+
2+ use std:: cmp:: Ordering ;
3+
4+ struct BinaryHeap < T , I > {
5+ data : Vec < T > ,
6+ comparator : I
7+ }
8+
9+ #[ inline] fn parent ( i : usize ) -> usize { ( i - 1 ) / 2 }
10+ #[ inline] fn left_child ( i : usize ) -> usize { i * 2 + 1 }
11+
12+ type DefaultCmp < T > = fn ( & T , & T ) -> Ordering ;
13+ impl < T : Ord > BinaryHeap < T , DefaultCmp < T > > {
14+ fn comparator ( a : & T , b : & T ) -> Ordering {
15+ a. cmp ( b)
16+ }
17+ fn from ( data : Vec < T > ) -> BinaryHeap < T , DefaultCmp < T > > {
18+ let mut ans = BinaryHeap {
19+ data,
20+ comparator : Self :: comparator as DefaultCmp < T > ,
21+ } ;
22+ ans. build_heap ( ) ;
23+ ans
24+ }
25+ fn new ( ) -> BinaryHeap < T , DefaultCmp < T > > {
26+ fn comparator < T : Ord > ( a : & T , b : & T ) -> Ordering {
27+ a. cmp ( b)
28+ }
29+ BinaryHeap {
30+ data : vec ! [ ] ,
31+ comparator : Self :: comparator as DefaultCmp < T > ,
32+ }
33+ }
34+ }
35+
36+ impl < T , I > BinaryHeap < T , I > where I : FnMut ( & T , & T ) -> Ordering {
37+ fn with_comparator ( comparator : I ) -> BinaryHeap < T , I > {
38+ BinaryHeap {
39+ data : vec ! [ ] ,
40+ comparator,
41+ }
42+ }
43+
44+ fn from_with_comparator ( data : Vec < T > , comparator : I ) -> BinaryHeap < T , I > {
45+ let mut ans = BinaryHeap {
46+ data,
47+ comparator,
48+ } ;
49+ ans. build_heap ( ) ;
50+ ans
51+ }
52+
53+ fn is_empty ( & self ) -> bool {
54+ self . data . is_empty ( )
55+ }
56+
57+ fn len ( & self ) -> usize {
58+ self . data . len ( )
59+ }
60+
61+ fn build_heap ( & mut self ) {
62+ if self . len ( ) < 2 { return ; }
63+ // if x is last internal index, then 2x+1 == self.len() - 1
64+ // x = (self.len() - 2) / 2;
65+ let last_internal = ( self . len ( ) - 2 ) / 2 ;
66+ for i in ( 0 ..=last_internal) . rev ( ) {
67+ self . sift_down ( i) ;
68+ }
69+ }
70+
71+ #[ inline]
72+ fn is_less ( & mut self , i : usize , j : usize ) -> bool {
73+ ( self . comparator ) ( & self . data [ i] , & self . data [ j] ) == Ordering :: Less
74+ }
75+
76+ fn sift_up ( & mut self , mut i : usize ) {
77+ // if a value > its parent
78+ while i != 0 {
79+ let parent_i = parent ( i) ;
80+ if self . is_less ( parent_i, i) {
81+ self . data . swap ( parent_i, i) ;
82+ i = parent_i;
83+ } else {
84+ break ;
85+ }
86+ }
87+ }
88+
89+ fn sift_down ( & mut self , mut i : usize ) {
90+ // if a value < max of its child
91+ loop {
92+ let lc_i = left_child ( i) ;
93+ if !self . contains_idx ( lc_i) { break ; } // has no left child
94+ let mut max_idx = if self . is_less ( i, lc_i) { lc_i } else { i } ;
95+ let rc_i = lc_i + 1 ;
96+ if self . contains_idx ( rc_i) && self . is_less ( max_idx, rc_i) {
97+ max_idx = rc_i;
98+ }
99+ if max_idx == i { break ; } // value >= max of its child
100+ self . data . swap ( i, max_idx) ;
101+ i = max_idx;
102+ }
103+ }
104+
105+ #[ inline]
106+ fn contains_idx ( & self , i : usize ) -> bool {
107+ i < self . data . len ( )
108+ }
109+
110+ fn push ( & mut self , v : T ) {
111+ self . data . push ( v) ;
112+ self . sift_up ( self . data . len ( ) - 1 ) ;
113+ }
114+
115+ fn pop ( & mut self ) -> Option < T > {
116+ if self . data . is_empty ( ) {
117+ return None ;
118+ }
119+ let ans = self . data . swap_remove ( 0 ) ;
120+ self . sift_down ( 0 ) ;
121+ Some ( ans)
122+ }
123+ }
124+
125+ #[ cfg( test) ]
126+ mod tests {
127+
128+ use super :: * ;
129+
130+ #[ test]
131+ fn test_basic_pq ( ) {
132+ let mut pq: BinaryHeap < i32 , _ > = BinaryHeap :: from_with_comparator (
133+ vec ! [ 2 , 1 , 6 , 3 , 9 , 7 , 4 , 8 , 5 ] ,
134+ |a, b| a. cmp ( b)
135+ ) ;
136+ for i in ( 1 ..=9 ) . rev ( ) {
137+ assert_eq ! ( Some ( i) , pq. pop( ) ) ;
138+ }
139+ assert_eq ! ( None , pq. pop( ) ) ;
140+ }
141+
142+ #[ test]
143+ fn test_default_cmp ( ) {
144+ let mut pq: BinaryHeap < i32 , _ > = BinaryHeap :: from ( vec ! [ 2 , 1 , 6 , 3 , 9 , 7 , 4 , 8 , 5 ] ) ;
145+ for i in ( 1 ..=9 ) . rev ( ) {
146+ assert_eq ! ( Some ( i) , pq. pop( ) ) ;
147+ }
148+ assert_eq ! ( None , pq. pop( ) ) ;
149+ }
150+ }
0 commit comments