数据结构之队列(优先队列)

概念

优先队列(Priority Queue)为一种不必遵守队列特性FIFO(先进先出)的有序线性表,其中每个元素都赋予一个优先级(Priority),加入元素时可任意加入,但有最高优先级者(Highest Priority Out First HPOF)则最先输出。

 

Java

在Java中,PriorityQueue 类实现了这样的一种有序队列。

PriorityQueue 是一个基于优先堆的无界优先队列。堆是一种特殊的树形数据结构,它满足以下两个条件:

  • 父节点的值总是大于或等于子节点的值
  • 每个节点的左子树和右子树也是一个堆

PriorityQueue 的主要方法包括:

  • add(E e):将指定的元素插入此优先队列。
  • offer(E e):将指定的元素插入此优先队列。
  • remove():获取并移除此队列的头,如果此队列为空,则返回 null 。
  • poll(): 获取并移除此队列的头,如果此队列为空,则返回 null 。
  • element():获取但不移除此队列的头,如果此队列为空,则抛出一个 NoSuchElementException 异常。
  • peek():获取但不移除此队列的头,如果此队列为空,则返回 null 。

创建 PriorityQueue 可传入一个 Comparator 对象,该对象用来对元素进行排序。Comparator 接口中只有一个方法 compare(),在 PriorityQueue 中决定元素的顺序:

1
int compare(T o1, T o2) 

该方法返回一个负整数、零或正整数,表示 o1 按照某种特定的顺序小于、等于或大于 o2。

复制代码
 1 import java.util.Comparator;
 2 import java.util.PriorityQueue;
 3 
 4 public class PriorityQueueExample {
 5     public static void main(String[] args) {
 6         // 创建一个自然排序的 PriorityQueue
 7         PriorityQueue<Integer> numbers = new PriorityQueue<>(new Comparator<Integer>() {
 8             @Override
 9             public int compare(Integer o1, Integer o2) {
10                 return o1.compareTo(o2);
11             }
12         });
13 
14         // 添加元素
15         numbers.add(4);
16         numbers.add(2);
17         numbers.add(5);
18         numbers.add(1);
19         numbers.add(3);
20 
21         System.out.println("Priority Queue: " + numbers);
22 
23         // 获取队列头部的元素
24         int peek = numbers.peek();
25         System.out.println("队列头部的元素是:" + peek);
26 
27         // 删除队列头部的元素
28         int poll = numbers.poll();
29         System.out.println("删除的元素是:" + poll);
30 
31         System.out.println("新的 Priority Queue: " + numbers);
32         // 队列中元素的存储顺序,与出队顺序不一定一致
33         while (!numbers.isEmpty()){
34             // 删除队列头部的元素
35             System.out.println("删除的元素是:" + numbers.poll());
36 
37         }
38     }
39 }
复制代码

输出:

1
2
3
4
5
6
7
8
Priority Queue: [1, 2, 5, 4, 3]
队列头部的元素是:1
删除的元素是:1
新的 Priority Queue: [2, 3, 5, 4]
删除的元素是:2
删除的元素是:3
删除的元素是:4
删除的元素是:5

  

Python

在Python中,我们可以使用heapq模块来实现优先队列。

复制代码
 1 import heapq
 2 
 3 # 初始化一个空堆结构
 4 h = []
 5 
 6 # 加入元素
 7 heapq.heappush(h, 5)
 8 heapq.heappush(h, 7)
 9 heapq.heappush(h, 3)
10 
11 # 弹出并返回最小的元素
12 print(heapq.heappop(h))  # 3
13 
14 # 查看最小的元素,不弹出
15 print(h[0])  # 5
16 
17 # 弹出后打印,以此类推,直到为空
18 while h:
19     print(heapq.heappop(h))  # 5 7
复制代码

输出:

1
2
3
4
1
3
3
5

  

通过heappop方法你会按照从小到大依次取出值。

 

列表转换堆

复制代码
 1 import heapq
 2 
 3 h = []
 4 # heapq._heapify_max(h)  # 将list h 转换为最大堆.最大堆(MaxHeap)根节点的值最大,每个父节点的值都比子节点的值要大
 5 heapq.heapify(h)  # 将list h 转换为最大堆.最大堆(MaxHeap)根节点的值最大,每个父节点的值都比子节点的值要大
 6 
 7 heapq.heappush(h, 1)
 8 heapq.heappush(h, 3)
 9 heapq.heappush(h, 5)
10 
11 print(heapq.heappop(h))  # 1
12 print(h[0])  # 3
13 
14 while h:
15     print(heapq.heappop(h))  # 3 5
复制代码

输出:

1
2
3
4
1
3
3
5

  

Javascript

复制代码
 1 class PriorityQueue {
 2     constructor() {
 3         this.items = [];
 4     }
 5 
 6     enqueue(element) {
 7         if (this.isEmpty()) {
 8             this.items.push(element);
 9         } else {
10             let added = false;
11             for (let i = 0; i < this.items.length; i++) {
12                 if (element.priority < this.items[i].priority) {
13                     this.items.splice(i, 0, element);
14                     added = true;
15                     break;
16                 }else if(element.priority==undefined && element < this.items[i]){
17                     this.items.splice(i, 0, element);
18                     added = true;
19                     break;
20                 }
21             }
22             if (!added) {
23                 this.items.push(element);
24             }
25         }
26     }
27 
28     dequeue() {
29         return this.items.shift();
30     }
31 
32     isEmpty() {
33         return this.items.length === 0;
34     }
35 }
36 
37 queue =new PriorityQueue()
38 queue.enqueue(2)
39 queue.enqueue(1)
40 queue.enqueue(9)
41 queue.enqueue(8)
42 console.log(queue)
43 while (!queue.isEmpty()){
44     console.log(queue.dequeue())
45 }
复制代码

输出:

1
2
3
4
5
PriorityQueue { items: [ 1, 2, 8, 9 ] }
1
2
8
9

  

 

posted @   Allen_Hao  阅读(420)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示