• 优先队列
    • 简介
    • 优先队列的实现:
    • 测试代码:
    • 练习

    优先队列

    简介

    普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (largest-in,first-out)的行为特征。

    优先队列是0个或多个元素的集合,每个元素都有一个优先权或值,对优先队列执行的操作有:

    1. 查找;
    2. 插入一个新元素;
    3. 删除。

    在最小优先队列(min priority queue)中,查找操作用来搜索优先权最小的元素,删除操作用来删除该元素;对于最大优先队列(max priority queue),查找操作用来搜索优先权最大的元素,删除操作用来删除该元素。优先权队列中的元素可以有相同的优先权,查找与删除操作可根据任意优先权进行。

    优先队列的实现:

    首先定义 PriorityQueue 结构体

    1. #[derive(Debug)]
    2. struct PriorityQueue<T> where T: PartialOrd + Clone {
    3. pq: Vec<T>
    4. }

    第二行的where T: PartialOrd + Clone指的是 PriorityQueue 存储的泛型 T 是满足 PartialOrdClone trait 约束的,意味着泛型 T 是可排序和克隆的。

    后面是一些基本的方法实现,比较简单,就直接看代码吧。这个优先队列是基于Vec实现的,有O(1)的插入和O(n)的最大/最小值出列。

    1. impl<T> PriorityQueue<T> where T: PartialOrd + Clone {
    2. fn new() -> PriorityQueue<T> {
    3. PriorityQueue { pq: Vec::new() }
    4. }
    5. fn len(&self) -> usize {
    6. self.pq.len()
    7. }
    8. fn is_empty(&self) -> bool {
    9. self.pq.len() == 0
    10. }
    11. fn insert(&mut self, value: T) {
    12. self.pq.push(value);
    13. }
    14. fn max(&self) -> Option<T> {
    15. if self.is_empty() { return None }
    16. let max = self.max_index();
    17. Some(self.pq[max].clone())
    18. }
    19. fn min(&self) -> Option<T> {
    20. if self.is_empty() { return None }
    21. let min = self.min_index();
    22. Some(self.pq[min].clone())
    23. }
    24. fn delete_max(&mut self) -> Option<T> {
    25. if self.is_empty() { return None; }
    26. let max = self.max_index();
    27. Some(self.pq.remove(max).clone())
    28. }
    29. fn delete_min(&mut self) -> Option<T> {
    30. if self.is_empty() { return None; }
    31. let min = self.min_index();
    32. Some(self.pq.remove(min).clone())
    33. }
    34. fn max_index(&self) -> usize {
    35. let mut max = 0;
    36. for i in 1..self.pq.len() - 1 {
    37. if self.pq[max] < self.pq[i] {
    38. max = i;
    39. }
    40. }
    41. max
    42. }
    43. fn min_index(&self) -> usize {
    44. let mut min = 0;
    45. for i in 0..self.pq.len() - 1 {
    46. if self.pq[i] < self.pq[i + 1] {
    47. min = i;
    48. }
    49. }
    50. min
    51. }
    52. }

    测试代码:

    1. fn test_keep_min() {
    2. let mut pq = PriorityQueue::new();
    3. pq.insert(3);
    4. pq.insert(2);
    5. pq.insert(1);
    6. pq.insert(4);
    7. assert!(pq.min().unwrap() == 1);
    8. }
    9. fn test_keep_max() {
    10. let mut pq = PriorityQueue::new();
    11. pq.insert(2);
    12. pq.insert(4);
    13. pq.insert(1);
    14. pq.insert(3);
    15. assert!(pq.max().unwrap() == 4);
    16. }
    17. fn test_is_empty() {
    18. let mut pq = PriorityQueue::new();
    19. assert!(pq.is_empty());
    20. pq.insert(1);
    21. assert!(!pq.is_empty());
    22. }
    23. fn test_len() {
    24. let mut pq = PriorityQueue::new();
    25. assert!(pq.len() == 0);
    26. pq.insert(2);
    27. pq.insert(4);
    28. pq.insert(1);
    29. assert!(pq.len() == 3);
    30. }
    31. fn test_delete_min() {
    32. let mut pq = PriorityQueue::new();
    33. pq.insert(3);
    34. pq.insert(2);
    35. pq.insert(1);
    36. pq.insert(4);
    37. assert!(pq.len() == 4);
    38. assert!(pq.delete_min().unwrap() == 1);
    39. assert!(pq.len() == 3);
    40. }
    41. fn test_delete_max() {
    42. let mut pq = PriorityQueue::new();
    43. pq.insert(2);
    44. pq.insert(10);
    45. pq.insert(1);
    46. pq.insert(6);
    47. pq.insert(3);
    48. assert!(pq.len() == 5);
    49. assert!(pq.delete_max().unwrap() == 10);
    50. assert!(pq.len() == 4);
    51. }
    52. fn main() {
    53. test_len();
    54. test_delete_max();
    55. test_delete_min();
    56. test_is_empty();
    57. test_keep_max();
    58. test_keep_min();
    59. }

    练习

    基于二叉堆实现一个优先队列,以达到O(1)的出列和O(log n)的入列