堆:
优先队列(Priority Queue):特殊的“队列”,取出元素的顺序是 依照元素的优先权(关键字)大小,而不是元素进入队列的先后顺序。
堆的两个特性 :
结构性:用数组表示的完全二叉树;
有序性:任一结点的关键字是其子树所有结点的最大值(或最小值)
“最大堆(MaxHeap)”,也称“大顶堆”:最大值
“最小堆(MinHeap)”,也称“小顶堆” :最小值
下面以最大堆(数组实现)为例,实现基本操作:
typedef struct priority_queue* heap;
struct priority_queue(int max){
elementtype* data;
int size;
int capacity;
};
-
创建:
heap create_maxheap(int max){ heap h=(heap)malloc(sizeof(struct priority_queue)); h->data=(elementtype*)malloc(sizeof(elementtype)*(max+1)); h->size=0; h->capacity=max; }
-
插入:
int is_full(heap h){ //判断堆是否满 return (h->size==h->capacity); } bool insert(elementtype x,heap h){ if (is_full(h)) return false; //最大堆已满 int i=++(h->size); //取插入位置,当前容量+1 while (i>1 && x>h->data[i/2]){ //未到达堆顶,且大于i的父亲节点 h->data[i]=h->data[i/2]; //相当于给x腾出空间 i/=2; } h->data[i]=x; //插入x return true; }
-
删除:
int is_empty(heap h){ //判断堆是否空 return (h->size==0); } elementtype delete_max(heap h){ //删除堆顶元素并返回 if (is_empty(h)) return false; //堆空 elementtype top=h->data[0]; //记录堆顶元素,待return elementtype temp=h->data[(h->size)--]; //记录最后一个元素,当前容量-1 int parent=1,child; for (; parent*2<=h->size; parent=child){ child=2*parent; if ( (child!=h->size) && (h->data[child]<h->data[child+1]) ) child++; //找到最大子节点(其中第一个条件判断是否有右儿子) if (temp>=h->data[child]) break; //让temp补位 else h->data[parent]=h->data[child]; //给temp腾出位置 } h->data[parent]=temp; //temp插入 return top; }