(一)优先队列和普通队列:
- 普通队列:先进先出的数据结构。
- 优先队列:元素被赋予优先级,依据优先级的大小出队,不再依照先来先服务的原则。
有几种不同的方式可以实现优先队列:
综合各种实现方式入队和出队的效果来看,使用完全二叉树实现优先队列的效率是最高的。
(二)堆
堆是一种优先队列,有两个特性:
- 结构性:堆是用数组表示的完全二叉树。
- 有序性:任一节点的关键字是其子树的最小值或者最大者。前者成为最小堆,后者为最大堆。
这两个特性又衍生出了堆的一个很重要的性质:对于最大堆,从根节点到任一叶子节点值的大小是递减的。对于最小堆,则反之,是递增的。
(三)堆的操作
- 结构
#include<stdio.h>
#include<stdlib.h>
typedef int ElementType;
#define MaxData 100000
typedef struct Heap {
ElementType *elements;
int size;
int capacity;
}*MaxHeap;
MaxHeap CreateEmpty(int MaxSize);
void Insert(MaxHeap h, ElementType element);
MaxHeap Create(ElementType s[]);
ElementType Delete(MaxHeap h);
- 插入
void Insert(MaxHeap h, ElementType element) {
//判断堆是否已满
if (h->size == h->capacity) return;
int i = ++h->size;
for (; h->elements[i / 2] < element; i /= 2)
h->elements[i] = h->elements[i / 2];
h->elements[i] = element;
}
- 删除
ElementType Delete(MaxHeap h) {
if (h->size == 0) return -1;
ElementType maxItem, temp;
maxItem = h->elements[1];
temp = h->elements[h->size--];
int parent, child;
for (parent = 1; parent * 2 <= h->size;parent = child) {
child = parent * 2;
if (child != h->size && h->elements[child + 1] > h->elements[child])
child++;
if (temp > h->elements[child])
break;
else
h->elements[parent] = h->elements[child];
}
h->elements[parent] = temp;
return maxItem;
}
- 创建
创建有两种方式:
- 通过插入操作,将N个元素逐一插入到初始为空的堆中,其时间代价最大为O(N * logN);
- 先将N个元素按输入顺序存储到数组中,满足堆的结构特性。然后在此基础上进行调整,以满足堆的有序性。时间复杂度为O(N)
Heap* InitHeap()
{
Heap *h = (Heap*)malloc(sizeof(Heap));
h->elements[0] = maxData;
h->size = 0;
h->capacity = maxSize;
return h;
}
void HeapAdjust(Heap *h)
{
int i, value;
int parent, child;
for(i = h->size / 2; i >= 1; i--)
{
value = h->elements[i];
for(parent = i; 2 * parent <= h->size; parent = child)
{
child = 2 * parent;
if(child != h->size && h->elements[child + 1] > h->elements[child])
child++;
if(value >= h->elements[child])
break;
else
h->elements[parent] = h->elements[child];
}
h->elements[parent] = value;
}
}
Heap* CreateHeap(int elements[], int length)
{
Heap *h = InitHeap();
for(int i = 0; i < length; i++)
h->elements[++h->size] = elements[i];
HeapAdjust(h);
return h;
}