rust_algorithms/data_structures/
heap.rs1#[derive(Debug, Clone, Default)]
40pub struct MinHeap<T: Ord> {
41 data: Vec<T>,
42}
43
44impl<T: Ord> MinHeap<T> {
45 pub fn new() -> Self {
47 Self { data: Vec::new() }
48 }
49
50 pub fn heapify(data: Vec<T>) -> Self {
63 let mut h = Self { data };
64 for i in (0..h.data.len() / 2).rev() {
65 h.sift_down(i);
66 }
67 h
68 }
69
70 pub fn push(&mut self, item: T) {
72 self.data.push(item);
73 self.sift_up(self.data.len() - 1);
74 }
75
76 pub fn pop(&mut self) -> Option<T> {
78 if self.data.is_empty() {
79 return None;
80 }
81 let oxirgi = self.data.len() - 1;
82 self.data.swap(0, oxirgi);
83 let min = self.data.pop();
84 if !self.data.is_empty() {
85 self.sift_down(0);
86 }
87 min
88 }
89
90 pub fn peek(&self) -> Option<&T> {
92 self.data.first()
93 }
94
95 pub fn len(&self) -> usize {
97 self.data.len()
98 }
99
100 pub fn is_empty(&self) -> bool {
102 self.data.is_empty()
103 }
104
105 pub fn into_sorted_vec(mut self) -> Vec<T> {
107 let mut out = Vec::with_capacity(self.data.len());
108 while let Some(x) = self.pop() {
109 out.push(x);
110 }
111 out
112 }
113
114 fn sift_up(&mut self, mut i: usize) {
116 while i > 0 {
117 let ota = (i - 1) / 2;
118 if self.data[i] >= self.data[ota] {
119 break;
120 }
121 self.data.swap(i, ota);
122 i = ota;
123 }
124 }
125
126 fn sift_down(&mut self, mut i: usize) {
128 let n = self.data.len();
129 loop {
130 let chap = 2 * i + 1;
131 if chap >= n {
132 break;
133 }
134 let ong = chap + 1;
135 let mut kichik = chap;
136 if ong < n && self.data[ong] < self.data[chap] {
137 kichik = ong;
138 }
139 if self.data[i] <= self.data[kichik] {
140 break;
141 }
142 self.data.swap(i, kichik);
143 i = kichik;
144 }
145 }
146}
147
148impl<T: Ord> FromIterator<T> for MinHeap<T> {
149 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
150 Self::heapify(iter.into_iter().collect())
151 }
152}
153
154#[cfg(test)]
155mod tests {
156 use super::*;
157 use crate::util::Rng;
158
159 #[test]
160 fn tartibda_chiqaradi() {
161 let mut rng = Rng::new(101);
162 let sonlar = rng.vec(500, -1000, 1000);
163 let heap: MinHeap<i64> = sonlar.iter().cloned().collect();
164 let chiqish = heap.into_sorted_vec();
165
166 let mut kutilgan = sonlar.clone();
167 kutilgan.sort_unstable();
168 assert_eq!(chiqish, kutilgan);
169 }
170
171 #[test]
172 fn bosh_heap() {
173 let mut h: MinHeap<i32> = MinHeap::new();
174 assert!(h.is_empty());
175 assert_eq!(h.pop(), None);
176 assert_eq!(h.peek(), None);
177 }
178
179 #[test]
180 fn push_pop_aralash() {
181 let mut h = MinHeap::new();
182 h.push(5);
183 h.push(3);
184 assert_eq!(h.pop(), Some(3));
185 h.push(1);
186 h.push(4);
187 assert_eq!(h.pop(), Some(1));
188 assert_eq!(h.pop(), Some(4));
189 assert_eq!(h.pop(), Some(5));
190 assert_eq!(h.pop(), None);
191 }
192
193 #[test]
194 fn heap_sharti_saqlanadi() {
195 let mut rng = Rng::new(202);
196 let mut h = MinHeap::new();
197 for _ in 0..200 {
198 h.push(rng.range(0, 100));
199 }
200 for i in 0..h.data.len() {
202 for f in [2 * i + 1, 2 * i + 2] {
203 if f < h.data.len() {
204 assert!(h.data[i] <= h.data[f]);
205 }
206 }
207 }
208 }
209}