优先队列原理与实现【转】
转自:优先队列原理与实现
优先队列是一种用来维护一组元素构成的结合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 }