1struct PriorityQueueNode<T> where T: Sized {
2 pub priority: u32,
3 pub value: Option<T>,
4}
5
6impl<T> PriorityQueueNode<T> {
7 pub fn new(priority: u32, value: T) -> PriorityQueueNode<T> {
8 PriorityQueueNode {
9 priority,
10 value: Some(value),
11 }
12 }
13}
14
15impl<T> Drop for PriorityQueueNode<T> {
16 fn drop(&mut self) {
17 }
19}
20
21
22struct PriorityQueue<T> where T: Sized {
23 pub nodes: Vec<Option<Box<PriorityQueueNode<T>>>>,
24}
25
26impl<T> PriorityQueue<T> {
27 pub fn new() -> PriorityQueue<T> {
28 PriorityQueue {
29 nodes: Vec::with_capacity(128),
30 }
31 }
32
33 pub fn pop(&mut self) -> Option<T> {
34 if self.nodes.len() < 1 {
35 return None;
36 }
37 let top = self.nodes[0].take();
38 let mut max_pos = 0;
39 let mut cur_pos = 0;
40
41 let bottom_node = self.nodes.pop().unwrap();
42 if self.nodes.len() < 1 {
43 return top.unwrap().value.take();
44 }
45
46 self.nodes[max_pos] = bottom_node;
47 let priority = self.nodes[max_pos].as_ref().unwrap().priority;
48 let queue_len = self.nodes.len();
49
50 loop {
51 let left_child_pos = max_pos * 2 + 1;
52 let right_child_pos = max_pos * 2 + 2;
53
54 if left_child_pos < queue_len && right_child_pos < queue_len {
55 let left_child_priority = self.nodes[left_child_pos].as_ref().unwrap().priority;
56 let right_child_priority = self.nodes[right_child_pos].as_ref().unwrap().priority;
57 if left_child_priority > right_child_priority {
58 max_pos = left_child_pos;
59 } else {
60 max_pos = right_child_pos;
61 }
62 } else if left_child_pos < queue_len {
63 let left_child_priority = self.nodes[left_child_pos].as_ref().unwrap().priority;
64 if left_child_priority > priority {
65 max_pos = left_child_pos;
66 }
67 } else if right_child_pos < queue_len {
68 let right_child_priority = self.nodes[right_child_pos].as_ref().unwrap().priority;
69 if right_child_priority > priority {
70 max_pos = right_child_pos;
71 }
72 }
73 if max_pos < 1 || cur_pos == max_pos {
74 break;
75 }
76 if priority > self.nodes[max_pos].as_ref().unwrap().priority {
77 break;
78 }
79
80 let cur_node = self.nodes[cur_pos].take();
81 let max_node = self.nodes[max_pos].take();
82 self.nodes[max_pos] = cur_node;
83 self.nodes[cur_pos] = max_node;
84 cur_pos = max_pos;
85 }
86 return top.unwrap().value.take();
87 }
88
89 pub fn peek(&mut self) -> Option<&mut T> {
90 if self.nodes.len() < 1 {
91 return None;
92 }
93 return self.nodes[0].as_mut().unwrap().value.as_mut();
94 }
95
96 pub fn push(&mut self, priority: u32, value: T) {
97 if self.nodes.len() < 1 {
98 self.nodes.push(Some(Box::new(PriorityQueueNode::new(priority, value))));
99 return;
100 }
101 let mut compare_pos = (self.nodes.len() - 1) / 2;
102 let new_node = PriorityQueueNode::new(priority, value);
103 self.nodes.push(Some(Box::new(new_node)));
104 let mut new_node_pos = self.nodes.len() - 1;
105 loop {
106 if priority > self.nodes[compare_pos].as_ref().unwrap().priority {
107 let new_node = self.nodes[new_node_pos].take();
108 self.nodes[new_node_pos] = self.nodes[compare_pos].take();
109 self.nodes[compare_pos] = new_node;
110 } else {
111 break;
112 }
113 if compare_pos < 1 {
114 break;
115 }
116 new_node_pos = compare_pos;
117 compare_pos = (compare_pos - 1) / 2;
118 }
119 }
120}
121
122#[cfg(test)]
123mod test {
124 use super::*;
125
126 #[test]
127 fn main() {
128 let mut queue = PriorityQueue::new();
129 for priority in 10..10000 {
130 queue.push(priority, String::from(format!("HelloWorld{}", priority)));
131 }
132
133 if let Some(t) = queue.peek() {
134 println!("peek {}", t);
135 }
136
137 for priority in 0..10 {
138 let value = queue.pop();
139 if let Some(t) = value {
140 println!("pop {}", t);
141 }
142 }
143
144 if let Some(t) = queue.peek() {
145 println!("peek {}", t);
146 }
147 }
148}