Skip to main content

rust_algorithms/data_structures/
heap.rs

1//! Binary heap (uyum) — prioritetli navbat.
2
3/// Min-heap: eng kichik element har doim tepada.
4///
5/// **G'oya:** to'liq binar daraxtni **massivda** saqlaymiz. `i` -indeksdagi tugun uchun:
6/// - ota: `(i - 1) / 2`
7/// - chap farzand: `2i + 1`, o'ng farzand: `2i + 2`
8///
9/// Yagona qoida (heap sharti): **ota farzandidan katta emas**.
10/// Shu qoidani buzmaslik uchun ikkita amal bor: `sift_up` (qo'shishda) va
11/// `sift_down` (o'chirishda). Ikkalasi ham daraxt balandligi bo'ylab yuradi → O(log n).
12///
13/// ```text
14///        1              massiv: [1, 3, 5, 7, 9, 8]
15///      /   \
16///     3     5           ota(4) = (4-1)/2 = 1  → qiymati 3
17///    / \   /
18///   7   9 8
19/// ```
20///
21/// **Qayerda ishlatiladi:** Dijkstra, A*, Huffman, "eng katta K ta element",
22/// vazifalar rejalashtiruvchisi (scheduler).
23///
24/// > Max-heap kerakmi? `std::cmp::Reverse` bilan o'rang yoki qiymatlarni manfiylang.
25///
26/// # Misol
27/// ```
28/// use rust_algorithms::data_structures::MinHeap;
29///
30/// let mut h = MinHeap::new();
31/// for x in [5, 1, 8, 3] {
32///     h.push(x);
33/// }
34/// assert_eq!(h.peek(), Some(&1));
35/// assert_eq!(h.pop(), Some(1));
36/// assert_eq!(h.pop(), Some(3));
37/// assert_eq!(h.len(), 2);
38/// ```
39#[derive(Debug, Clone, Default)]
40pub struct MinHeap<T: Ord> {
41    data: Vec<T>,
42}
43
44impl<T: Ord> MinHeap<T> {
45    /// Bo'sh heap.
46    pub fn new() -> Self {
47        Self { data: Vec::new() }
48    }
49
50    /// Tayyor vektordan heap quradi — **O(n)** (n log n emas!).
51    ///
52    /// Pastdan yuqoriga `sift_down` qilish n log n emas, chiziqli vaqt beradi:
53    /// tugunlarning yarmi bargda (0 qadam), choragi bir qavat yuqorida (1 qadam)…
54    ///
55    /// # Misol
56    /// ```
57    /// use rust_algorithms::data_structures::MinHeap;
58    ///
59    /// let h = MinHeap::heapify(vec![9, 4, 7, 1, 2]);
60    /// assert_eq!(h.peek(), Some(&1));
61    /// ```
62    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    /// Element qo'shadi. O(log n).
71    pub fn push(&mut self, item: T) {
72        self.data.push(item);
73        self.sift_up(self.data.len() - 1);
74    }
75
76    /// Eng kichik elementni olib chiqadi. O(log n).
77    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    /// Eng kichik elementga qaraydi. O(1).
91    pub fn peek(&self) -> Option<&T> {
92        self.data.first()
93    }
94
95    /// Elementlar soni.
96    pub fn len(&self) -> usize {
97        self.data.len()
98    }
99
100    /// Bo'shmi?
101    pub fn is_empty(&self) -> bool {
102        self.data.is_empty()
103    }
104
105    /// Heapni tartiblangan vektorga aylantiradi (heap sort). O(n log n).
106    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    /// Yangi qo'shilgan elementni yuqoriga ko'taradi.
115    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    /// Ildizdagi elementni pastga tushiradi.
127    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        // har bir ota farzandlaridan katta emas
201        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}