1.什么是堆
计算机处理数据需要按照一定的顺序,最简单的顺序就是先来后到,按时间顺序来处理数据。但有时,计算机需要处理的数据有优先级别。比如,打印一张纸排在了发射火箭前面,显然发射火箭比打印一张纸要重要的多,但如果按照时间先后顺序来处理的话,就会先打印一张纸再发射火箭,这显然是不合理的。这时我们就需要一种优先队列(Priority Queue)来应对这种情况。
优先队列(Priority Queue):特殊的“队列”,取出元素的顺序是按照元素的优先权(关键字)的大小,而不是元素进入队列的先后顺序。
采用数组,链表,有序数组和无序数组的形式都可以实现优先队列,但是都各有不足。于是考虑使用二叉树的形式来实现优先队列,这就有了堆的概念。
将最大值存放在跟结点,且任何一个子树的跟结点都是该子树的最大值(或最小值)。这样使用数组构成的完全二叉树就是堆。使用最大值构成的堆称为最大堆(MaxHeap)使用最小值构成的堆称为最小堆(MinHeap)
2.堆的结构,插入删除和建立。
2.1最大堆的操作集
以最大堆为例,他的操作集有:
·MaxHeap Create(int Maxsize):创建一个空的最大堆。
·Boolean IsFull(MaxHeap H):判断最大堆H是否已满。
·Insert(MaxHeap H, ElementType item):将元素item插入最大堆H。
·Boolean IsEmpty(MaxHeap H):判断最大堆H是否已空。
·ElemenType DeleteMax(MaxHeap H):返回H中的最大元素。
2.2最大堆的结构
//最大堆的实现
//堆的结构
typedef struct HeapStruct *MaxHeap;
struct HeapStruct {
int *Elements;
int Size;//堆的当前容量
int Capacity;//堆的最大容量
};
//建堆函数
MaxHeap Creat(int MaxSize) {
MaxHeap H = (MaxHeap)malloc(sizeof(struct HeapStruct));
H->Elements = (int)malloc(sizeof(int)*(MaxSize));
H->Capacity = MaxSize;
H->Size = 0;
//H->Elements[0] = MaxData;
return H;
}
2.3最大堆的插入操作
//最大堆的插入
void Insert(MaxHeap H, int X) {
int i;
if (Isfull(H)) {
printf("最大堆已满");
return;
}
i = ++H->Size;
for (; H->Elements[i / 2] < X; i /= 2)
H->Elements[i] = H->Elements[i / 2];
H->Elements[i] = X;
}
2.4最大堆的删除操作
//最大堆的删除
int Delete(MaxHeap H) {
int Parent, Child;
int MaxItem, temp;
if (IsEmpty(H)) {
printf("最大堆为空");
return;
}
MaxItem = H->Elements[1];
temp = H->Elements[H->Size--];
for (Parent = 1; Parent * 2 < H->Size; Parent = Child) {
Child = Parent * 2;
if (!Child == H->Size&&H->Elements[Child] <= H->Elements[Child + 1])
Child++;
if (temp < H->Elements[Child])
H->Elements[Child] = H->Elements[Parent];
else break;
}
H->Elements[Parent] = temp;
return MaxItem
}
2.5最大堆的建立操作
//堆的建立
MaxHeap MakeMaxHeap(int MaxSize) {
MaxHeap T = Creat(MaxSize);
int temp;
for (int i = T->Size / 2; i > 0; i--) {
int Parent, Child;
temp = T->Elements[i];
for (Parent = i; Parent * 2 < T->Size; Parent = Child) {
Child = Parent * 2;
if (!Child == T->Size&&Child <= Child + 1)
Child++;
if (temp < T->Elements[Child])
T->Elements[Parent] = T->Elements[Child];
else break;
}
T->Elements[Parent] = temp;
}
return T;
}