用代码说话
/*
本代码实现优先队列:分为最大优秀队列和最小优先队列
优先队列用于维护一组元素构成的集合S的数据结构,其中的
每一个元素都有一个相关的值,称为关键字。
一个最大优先队列支持以下操作:
insert(S,x)向S中插入元素x;
maximum(S)返回S中的最大键值元素;
extract-max(S)去掉并且返回S中的最大键值元素;
increase-key(S,x,k)将元素x的关键字增加到k,假设k要不小于x的原关键字
一个最小优先队列支持以下操作:
insert(S,x)向S中插入元素x;
minimum(S)返回S中的最小键值元素;
extract-min(S)去掉并且返回S中的最小键值元素;
decrease-key(S,x,k)将元素x的关键字减小到k,假设k要不大于x的原关键字
最大优先队列可以应用与操作系统的作业调度
最小优先队列可以用于基于事件驱动的模拟器
本文将实现最大优先队列
优先队列可以用堆来实现
*/
#include<stdio.h>
#include<stdlib.h>
#define N 6
static int heapSize=N;
/*
返回父节点和子节点索引
*/
//返回父结点
int parent(int index)
{
return (index-1)/2;
}
//返回左孩子
int left(int index)
{
return (index<<1)+1;
}
//返回右孩子
int right(int index)
{
return (index+1)<<1;
}
/*
维护堆的性质,即把不符合要求的元素重新组织
时间复杂度为logn
*/
int maxHeapify(int *A,int index,int size)
{
int L=left(index);
int R=right(index);
int tmp;
int largestIndex;
if(L<size && *(A+index)<*(A+L)) {
largestIndex=L;
} else {
largestIndex=index;
}
if(R<size && *(A+largestIndex)<*(A+R)) {
largestIndex=R;
}
if(index!=largestIndex) {
tmp=*(A+index);
*(A+index)=*(A+largestIndex);
*(A+largestIndex)=tmp;
maxHeapify(A,largestIndex,size);
}
return 0;
}
/*
对除没有子结点的结点进行堆的维护操作,进而
使得一个数组变成一个最大堆
时间复杂度为nlogn
*/
int buildMaxHeap(int *A)
{
int size=N;
//找出不是叶子结点的最后一个索引
int need=heapSize/2-1;
int i;
for(i=need;i>=0;i--) {
maxHeapify(A,i,heapSize);
}
return 0;
}
/*
堆排序程序
通过根元素始终是最大的,因此我们倒过来找
从最大的元素依次往最小的元素去排序
*/
int heapSort(int *A)
{
buildMaxHeap(A);
int j;
int size=heapSize;
int i;
int tmp;
for(i=N-1;i>=1;i--) {
tmp=*A;
*A=*(A+i);
*(A+i)=tmp;
size--;
maxHeapify(A,0,size);
}
return 0;
}
//------------------以下为优先队列的操作-----------------------//
/*
返回堆的最大值
*/
int heapMaxElement(int *A)
{
return A[0];
}
/*
获取堆的最大值并移除该最大值
*/
int heapExtractMax(int *A)
{
if(N<1) {
printf("Heap error!");
}
int max=heapMaxElement(A);
A[0]=A[heapSize-1];
heapSize=heapSize-1;
maxHeapify(A,0,heapSize);
return max;
}
/*
增加第i个元素的值,然后重新构建堆
*/
int heapIncreaseKey(int *A,int index,int newValue)
{
if(newValue<*(A+index)) {
printf("新增加的值应该要比原值大!");
return 1;
}
*(A+index)=newValue;
while(index>0&&*(A+index)>*(A+parent(index))) {
int temp;
temp=*(A+index);
*(A+index)=*(A+parent(index));
*(A+parent(index))=temp;
index=parent(index);
}
return 0;
}
/*
向最大堆中插入元素
*/
int heapInsert(int *A,int key)
{
heapSize=heapSize+1;
int *b=malloc(sizeof(int)*heapSize);
b=A;
*(b+heapSize-1)=key-1;
heapIncreaseKey(b,heapSize-1,key);
A=b;
return 0;
}
int main()
{
int b[N]={2,1,3,2,5,4};
int* a=b;
//必做:构建最大堆
buildMaxHeap(a);
printf("增加第一个元素的值为6\n");
heapIncreaseKey(a,0,6);
printf("%d\n",*a);
printf("向堆中插入7\n");
heapInsert(a,7);
printf("%d\n",*a);
printf("输出顶部元素\n");
printf("%d\n",*a);
printf("弹出顶部元素\n");
printf("%d\n",heapExtractMax(a));
printf("输出顶部元素\n");
printf("%d\n",*a);
return 0;
}
运行结果
zzw@zzw-ThinkPad-Edge-E430c:~/Algorithms/chap6/demo1$ ./priorityQueue
增加第一个元素的值为6
6
向堆中插入7
7
输出顶部元素
7
弹出顶部元素
7
输出顶部元素
6