在数据结构里,堆可以实现优先队列。
优先队列(priority queue)是0个或多个元素的集合,每个元素都有一个优先权或值,对优先队列执行的操作有1) 查找;2) 插入一个新元素;3) 删除。在最小优先队列中,查找操作用来搜索优先权最小的元素,删除操作用来删除该元素;对于最大优先队列(max priority queue),查找操作用来搜索优先权最大的元素,删除操作用来删除该元素。优先权队列中的元素可以有相同的优先权,查找与删除操作可根据任意优先权进行。
抽象数据类型M a x P r i o r i t y Q u e u e{
实例
有限的元素集合,每个元素都有一个优先权
操作
C reate ( ):创建一个空的优先队列
Size ( ):返回队列中的元素数目
Max ( ):返回具有最大优先权的元素
I n s e rt (x):将x 插入队列
DeleteMax (x):从队列中删除具有最大优先权的元素,并将该元素返回至x
}
堆
定义:[最大树(最小树)] 每个节点的值都大于(小于)或等于其子节点(如果有的话)值的树。
最大树(max tree)与最小树( min tree)的例子分别如图9 - 1、9 - 2所示,虽然这些树都是二叉树,但最大树不必是二叉树,最大树或最小树节点的子节点个数可以大于2。
定义:[最大堆(最小堆)] 最大(最小)的完全二叉树。
图9-1b 所示的最大树并不是最大堆( max heap),另外两个最大树是最大堆。图9-2b 所示的最小树不是最小堆(min heap),而另外两个是。
贴代码:
//定义堆
typedef char Element;
typedef struct BiTNode
{
int MaxSize;
int CurrentSize;
Element *heap;
}BiTNode,*BiTree;
void createHeap(BiTree &T,int maxsize)
{
T.MaxSize = maxsize;
T.heap = (Element*)malloc(sizeof(BiTNode)*maxsize+1);
T.CurrentSize = 0;
}
//插入操作
void insert(BiTree &T, const Element x)
{
//先判断堆是不是满
if(T.CurrentSize == T.MaxSize)
{
printf("堆空间满\n");
return;
}
int i = ++T.CurrentSize;
while( i != 1 && x > T.heap[i/2])
{
/**
* 如果x > T.heap[i/2],说明插入增加的节点的
* 父节点是小于x的,按照最大堆的规则,x要
* 在这个父节点之上,所以要把父节点下移到
* 增加的节点的位置。
*/
T.heap[i] = T.heap[i/2];
//把插入节点定位到父节点移动后的空出了位置
i = i/2;
}
T.heap[i] = x;
}
//删除最大堆的最大值
void DelMaxHeap(BiTree &T, Element E)
{
//判读堆是不是为空
if(0 == T.CurrentSize)
{
printf("堆为空,不能删除元素\n");
return;
}
//取出最大值
E = T.heap[1];
Element y = T.heap[T.CurrentSize];
CurrentSize--;
int i = 1;//当前空缺位置
int maxChild = 2;//记录当前空缺的孩子的最大元素的索引
while(maxChild <= T.CurrentSize)
{
//先找到i的最大孩子
if(maxChild < T.CurrentSize
&& T.heap[maxChild] < T.heap[maxChild+1])
maxChild++;
//判断y能不能放入
//1、能
if(y >= T.heap[i])
break;
//2、不能
//将孩子节点上移,空缺出孩子的节点最为下一次
//判断y能不能放入.
T.heap[i] = T.heap[maxChild];
i = maxChild;
maxChild *=2;
}
T.heap[i] = y;
}
/**
* 自己背写的
*/
//最大堆的插入
void MaxHeapInsert(BiTree &T , Element E)
{
if(T.CurrentSize == T.MaxSize)
{
printf("堆空间满\n");
return;
}
int i = ++T.CurrentSize;
while(1 != i && E > T.heap[i/2])
{
T.heap[i] = T.heap[i/2];
i = i/2;
}
T.heap[i] = E;
}
//最大堆的删除最大值
void DelMaxHeap(BiTree &T, Element E)
{
if(0 == T.CurrentSize)
{
printf("堆为空,不能删除元素\n");
return;
}
E = T.heap[1];
Element y = T.heap[T.CurrentSize];
T.CurrentSize--;
int i = 1;
int maxChild = 2;
while(maxChild <= T.CurrentSize)
{
if( maxChild<T.CurrentSize && T.heap[maxChild] < T.heap[maxChild+1])
maxChild++;
if(y >= T.heap[maxChild])
break;
T.heap[i] = T.heap[maxChild];
i = maxChild;
maxChild *= 2;
}
T.heap[i] = y;
}