rusty_structures/priority_queue/
dheap.rs1use std::fmt::Display;
2
3use crate::priority_queue::pair::Pair;
4
5#[derive(Debug)]
6pub struct DHeap<T: Clone + Display + PartialEq> {
7 data: Vec<Pair<T>>,
8 branching_factor: usize
9}
10
11impl<T: Clone + Display + PartialEq> DHeap<T> {
12 pub fn new(initial_capacity: Option<usize>, branching_factor: Option<usize>) -> Self {
13 match initial_capacity {
14 Some(v) => DHeap { data: Vec::with_capacity(v),
15 branching_factor: branching_factor.unwrap_or(2)},
16 None => DHeap { data: Vec::new(),
17 branching_factor: branching_factor.unwrap_or(2)},
18 }
19 }
20
21 pub fn heapify(&mut self)
22 {
23 let mut max_index = (self.data.len() - 1) / self.branching_factor;
24 while max_index != 0 {
25 self.push_down_optimized(Some(max_index));
26 max_index -= 1;
27 }
28 }
29
30 pub fn insert(&mut self, element: Pair<T>) {
31 self.data.push(element);
32 self.bubble_up(None);
33 }
34
35 pub fn peek(&self) -> Option<&Pair<T>> {
36 if self.data.len() == 0 {
37 None
38 } else {
39 Some(&self.data[0])
40 }
41 }
42
43 pub fn update_priority(&mut self, old_value: T, new_priority: usize) {
44 if let Some(index) = self.find_index(old_value) {
45 let temp = self.data[index].clone();
46 self.data.remove(index);
47 let updated_pair = Pair {
48 element: temp.element,
49 priority: new_priority
50 };
51 self.insert(updated_pair);
52 }
53 }
54
55 fn find_index(&self, old_value: T) -> Option<usize> {
56 for (index, pair) in self.data.iter().enumerate() {
57 if pair.element == old_value {
58 return Some(index);
59 }
60 }
61 None
62 }
63
64 pub fn top(&mut self) -> Option<Pair<T>> {
65 let last_element = self.remove_last()?;
66 if self.data.is_empty() {
67 Some(last_element)
68 } else {
69 let root_element = self.data[0].clone();
70 self.data[0] = last_element;
71 self.push_down_optimized(None);
72 Some(root_element)
73 }
74 }
75
76 fn remove_last(&mut self) -> Option<Pair<T>> {
77 if self.data.is_empty() {
78 None
79 } else {
80 self.data.pop()
81 }
82 }
83
84 fn bubble_up(&mut self, index: Option<usize>) {
86 let mut parent_index = index.unwrap_or(self.data.len() - 1);
88 while parent_index > 0 {
89 let current_index = parent_index;
90 parent_index = self.get_parent_index(parent_index);
91 if self.data[parent_index].priority < self.data[current_index].priority {
92 self.swap(current_index, parent_index)
93 } else {
94 break;
95 }
96 }
97 }
98
99 fn bubble_up_optimized(&mut self, initial_index: Option<usize>) {
100 let mut index = initial_index.unwrap_or(self.data.len() - 1);
101 let current = self.data[index].clone();
102 while index > 0 {
103 let parent_index = self.get_parent_index(index);
104 if self.data[parent_index].priority < self.data[index].priority {
105 self.data[index] = self.data[parent_index].clone();
106 index = parent_index;
107 } else {
108 break;
109 }
110 }
111 self.data[index] = current;
112 }
113
114 fn push_down(&mut self, initial_index: Option<usize>) {
115 let index = initial_index.unwrap_or(0);
116 let mut current_index = index;
117 while current_index < self.first_leaf_index() {
118 let highest_priority_child_index = self.highest_priority_child_index(index);
119 if self.data[current_index].priority < self.data[highest_priority_child_index].priority {
120 self.swap(current_index,highest_priority_child_index);
121 current_index = highest_priority_child_index;
122 } else {
123 break;
124 }
125 }
126 }
127
128 fn push_down_optimized(&mut self, initial_index: Option<usize>) {
129 let mut index = initial_index.unwrap_or(0);
130 let current = self.data[index].clone();
131 while index < self.first_leaf_index() {
132 let highest_priority_child_index = self.highest_priority_child_index(index);
133 if self.data[index].priority < self.data[highest_priority_child_index].priority {
134 self.data[index] = self.data[highest_priority_child_index].clone();
135 index = highest_priority_child_index;
136 } else {
137 break;
138 }
139 }
140 self.data[index] = current;
141 }
142
143 fn first_leaf_index(&self) -> usize {
144 (self.data.len() - 2) / self.branching_factor + 1
145 }
146
147 fn get_parent_index(&self, index: usize) -> usize {
148 (index - 1) / self.branching_factor
149 }
150
151 fn swap(&mut self, first_index: usize, second_index: usize) {
152 self.data.swap(first_index, second_index);
153 }
154
155 pub fn highest_priority_child_index(&self, index: usize) -> usize {
156 let first_child_index = (self.branching_factor * index) + 1;
158 if self.data.len() - 1 < first_child_index {
159 return index;
160 }
161
162 let mut highest_priority_index = index;
163 for i in 1..=self.branching_factor {
164 let child_index = (self.branching_factor * index) + i;
165 if self.data.len() - 1 < child_index {
166 continue;
167 }
168
169 if self.data[child_index].priority > self.data[highest_priority_index].priority {
170 highest_priority_index = child_index;
171 }
172 }
173 highest_priority_index
174 }
175}
176
177#[derive(Debug)]
178enum DheapError {
179 EmptyHeap
180}
181
182impl std::error::Error for DheapError {}
183impl Display for DheapError {
184 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
185 match self {
186 Self::EmptyHeap => write!(f, "empty heap")
187 }
188 }
189}
190
191mod tests {
192 use super::*;
193
194 fn testing_dheap() -> DHeap<String> {
195 let mut heap = DHeap::new(None, None);
196 for i in 1..10 {
197 let example_pair = Pair {priority: i, element: i.to_string()};
198 heap.insert(example_pair);
199 }
200 heap
201 }
202
203 #[test]
204 fn get_top_test() {
205 let mut heap = testing_dheap();
206 let received = heap.top().unwrap();
207 let expected = Pair {priority: 9, element: 9.to_string()};
208
209 assert_eq!(expected.priority, received.priority);
210 assert_eq!(expected.element, received.element);
211 }
212
213 #[test]
214 fn peek_test() {
215 let heap = testing_dheap();
216 let pair = heap.peek().unwrap();
217 assert_eq!(9, pair.priority);
218 }
219
220 #[test]
221 fn update_is_correct() {
222 let mut heap = testing_dheap();
223 heap.update_priority("9".to_string(), 10);
224 let top_pair = heap.top().unwrap();
225 assert_eq!(10, top_pair.priority);
226 }
227}