转自:优先队列原理与实现
优先队列是一种用来维护一组元素构成的结合S的数据结构,其中每个元素都有一个关键字key,元素之间的比较都是通过key来比较的。优先队列包括最大优先队列和最小优先队列,优先队列的应用比较广泛,比如作业系统中的调度程序,当一个作业完成后,需要在所有等待调度的作业中选择一个优先级最高的作业来执行,并且也可以添加一个新的作业到作业的优先队列中。Java中,PriorityQueue的底层数据结构就是堆(默认是小堆),关于Java的PriorityQueue更多知识请点击:深入理解Java PriorityQueue。
优先队列的实现中,我们可以选择堆数据结构,最大优先队列可以选用大堆,最小优先队列可以选用小堆来实现。下面以最大优先队列来讲解其原理。最大优先队列一般包括将一个元素插入到集合S中、返回集合S中具有最大key的元素、返回并删除集合S中具有最大key的元素等。
插入操作
插入操作是将一个元素插入到集合S中,首先把该元素放入所有元素的下一位置,然后执行“上浮”操作,如下图示例(注意,下图示例是小堆,不过原理是一样的,图片来自深入理解Java PriorityQueue)
)
移除操作
优先队列中,在队列非空情况下移除集合中第一个元素,也就是下标为0的元素,然后将集合中最后一个元素移到下标为0位置,在将下标为0的新元素执行“下沉”操作。如下图示例(注意,下图示例是小堆,不过原理是一样的,图片来自深入理解Java PriorityQueue)
1 #include<iostream>
2 using namespace std;
3
4 const int maxn=1000;
5
6 int n;
7 int heap[maxn];
8
9 void heap_pop()
10 {
11 swap(heap[1],heap[n]);
12 n--;
13 for(int i=1,j;i<=n;i=j)
14 {
15 if(i*2+1>n||heap[i*2])
16 j=i*2;
17 else
18 j=i*2+1;
19 if(heap[i]>heap[j])
20 swap(heap[i],heap[j]);
21 else
22 break;
23 }
24 }
25
26 void heap_insert(int x)
27 {
28 heap[++n]=x;
29 for(int i=n,j;i>1;i=j)
30 {
31 j=i/2;
32 if(heap[i]<heap[j])
33 swap(heap[i],heap[j]);
34 else
35 break;
36 }
37 }