优先队列
首先搞清楚 什么是优先队列,优先队列是一种数据结构,它与一般的队列先入先出的性质不同,它每次出队的是优先级最大的元素,当一个指定的优先级元素入队时,能够很快的把它排到队列中。看到这里,可以发现,优先队列其实就是堆排序方法的设计与实现。
堆 其实是一种完全二叉树,这个结构明显的好处是可以用数组来表示,不用指针来表示,这样我们可以省去很多不必要的麻烦。这里最大堆和最小堆的概念可以查看严蔚敏的数据结构神书。堆排序的过程大家可以再百度上寻找,这里也不详细介绍。
然后说一下优先队列,需要如下集中关键的操作。
(1)push() :将元素插入到优先队列。
(2)top():返回优先级最高的元素.
(3) pop():弹出优先级最高的元素。
(4)increase():将某一个元素的优先级提升到某个数。
top()函数只要返回数组的第一个元素就可以了,期就为最大值, pop函数主要功能是弹出最大的元素,让数组的第一个元素与最后一个元素交换一下,然后将数组的长度减1,然后调整堆就可以了, increase函数将A[i]的设为指定的优先级。然后在i>1且A[i]的父节点一直小于A[i]的情况下,一直做两件事:a.交换A[i]与它的父节点的值。b.将i递增为父节点的序号。
具体的实现代码
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
typedef struct List
{
int *data;
int length;
int size;
}*pArrayList;
void heapAdjust(pArrayList list,int index,int length)
{
int lchild=index*2+1;
int rchild=index*2+2;
int largest;
if(lchild<=length && list->data[lchild]>list->data[index])
{
largest=lchild;
}
else
largest=index;
if(rchild<=length && list->data[rchild]>list->data[largest])
{
largest=rchild;
}
if(largest!=index)
{
int tmp=list->data[index];
list->data[index]=list->data[largest];
list->data[largest]=tmp;
heapAdjust(list,largest,length);
}
}
void BuildMaxHeap(pArrayList list)
{
for(int i=(list->length-2)/2;i>=0;i--)
{
heapAdjust(list,i,list->length);
}
}
void printArrayList(pArrayList list)
{
for(int i=0;i<list->length;i++)
{
printf("%d ",list->data[i]);
}
printf("\n");
}
void heapSort(pArrayList list)
{
BuildMaxHeap(list);
printf("构成最大堆:");
printArrayList(list);
int len=list->length-1;
for(int i=list->length-1;i>0;--i)
{
int tmp=list->data[0];
list->data[0]=list->data[i];
list->data[i]=tmp;
printf("交换以后:");
printArrayList(list);
--len;
heapAdjust(list,0,len);
}
printf("最终结果:");
printArrayList(list);
}
int top(pArrayList list)
{
return list->data[0];
}
int pop(pArrayList list)
{
int head=list->data[0];
list->data[0]=list->data[list->length-1];
--list->length;
heapAdjust(list,0,list->length);
return head;
}
int max(int a,int b)
{
return a>b?a:b;
}
void decreaseKey(pArrayList list,int index,int key)
{
if(list->data[index]<key)
{
printf("new key must be smaller");
return ;
}
else
{
list->data[index]=key;
}
int tmp;
while(index<list->length&& max(list->data[index*2+1],list->data[index*2+2])>list->data[index])
{
int itmp;
tmp=list->data[index];
list->data[index]=max(list->data[index*2+1],list->data[index*2+2]);
if(list->data[index*2+1]==max(list->data[index*2+1],list->data[index*2+2]))
{
itmp=index*2+1;
}
else
{
itmp=index*2+2;
}
list->data[itmp]=tmp;
index=itmp;
}
}
void increaseKey(pArrayList list,int index ,int key)
{
if(list->data[index]>key)
{
printf("new Key must be bigger ");
return ;
}
else
{
list->data[index]=key;
}
int tmp;
while(index>0 && list->data[(index-2)/2]<list->data[index])
{
tmp=list->data[index];
list->data[index]=list->data[(index-2)/2];
list->data[(index-2)/2]=tmp;
index=(index-2) / 2;
}
}
void push(pArrayList list, int key)
{
if(list->length==list->size)
{
list->data=(int *)realloc(list->data,sizeof(int) * list->size * 2);
list->size=list->size*2;
}
list->data[list->length]=-1;
increaseKey(list,list->length,key);
++list->length;
BuildMaxHeap(list);
}
void main()
{
pArrayList list;
list=(pArrayList)malloc(sizeof(List));
list->data=(int *)malloc(sizeof(int)*5);
for(int i=0;i<5;i++)
{
list->data[i]=i;
}
list->length=5;
list->size=5;
BuildMaxHeap(list);
//increaseKey(list,3,7);
decreaseKey(list,0,1);
//push(list,8);
//BuildMaxHeap(list);
printArrayList(list);
printf("%d\n",top(list));
}

浙公网安备 33010602011771号