数据结构与算法分析-二叉堆
二叉堆是一棵完全二叉树,具有结构性和堆序性,父节点小于等于子节点;
它可以用数组表示,不需要指针,对于数组中任意位置i上的元素,其左儿子节点在2i上,右儿子节点在(2i + 1)上,它的父节点则在位子[i / 2]上;
使用数组实现堆的方法需要事先估计堆的大小;
#include <stdio.h> #include <stdlib.h> #include <string.h> #define ElementType int //堆元素类型 #define MinPQSize 5 //struct HeapStruct; //typedef struct HeapStruct *PriorityQueue; struct HeapStruct { int Capacity; int Size; ElementType *Elements; }; typedef struct HeapStruct *PriorityQueue; PriorityQueue Initialize(int MaxElements); void Destory(PriorityQueue H); void MakeEmpty(PriorityQueue H); void Insert(ElementType X, PriorityQueue H); ElementType DeleteMin(PriorityQueue H); ElementType FindMin(PriorityQueue H); int IsEmpty(PriorityQueue H); int IsFull(PriorityQueue H); void Display(PriorityQueue H); const ElementType MinData = -1; PriorityQueue Initialize(int MaxElements) { PriorityQueue H = NULL; if (MaxElements < MinPQSize) { printf("priority queue size is too small!\n"); return NULL; } H = (PriorityQueue)malloc(sizeof(struct HeapStruct)); if (NULL == H) { printf("malloc Heap error!\n"); return NULL; } H->Elements = (ElementType *)malloc((MaxElements + 1) * sizeof(ElementType)); if (NULL == H->Elements) { printf("malloc Elements error!\n"); return NULL; } H->Capacity = MaxElements; H->Size = 0; H->Elements[0] = MinData; return H; } void Destory(PriorityQueue H) { if (NULL != H) { if (NULL != H->Elements) { free(H->Elements); H->Elements = NULL; } H->Capacity = 0; H->Size = 0; free(H); H= NULL; } return; } void MakeEmpty(PriorityQueue H) { if (NULL != H) { if (NULL != H->Elements) { memset(H->Elements + 1, 0, H->Size * sizeof(ElementType)); } H->Capacity = 0; H->Size = 0; } return; } void Insert(ElementType X, PriorityQueue H) { int i = 0; if (NULL == H) { printf("H is NULL!\n"); return; } if (IsFull(H)) { printf("priority queue is full!\n"); return; } for (i = ++H->Size; H->Elements[i / 2] > X; i /= 2) //上虑 { H->Elements[i] = H->Elements[i / 2]; } H->Elements[i] = X; return; } ElementType DeleteMin(PriorityQueue H) { int i, Child; ElementType MinElement, LastElement; if (NULL == H) { printf("H is NULL!\n"); return -2; } if (IsEmpty(H)) { printf("priority queue is empty!\n"); return -3; } MinElement = H->Elements[1]; LastElement = H->Elements[H->Size--]; for (i = 1; 2 * i <= H->Size; i = Child) //下虑 { Child = 2 * i; if ((Child < H->Size) && (H->Elements[Child + 1] < H->Elements[Child])) { Child += 1; } if (LastElement > H->Elements[Child]) { H->Elements[i] = H->Elements[Child]; } else { break; } } H->Elements[i] = LastElement; return MinElement; } ElementType FindMin(PriorityQueue H) { if (NULL == H) { printf("H is NULL!\n"); return -4; } if (IsEmpty(H)) { printf("priority queue is empty!\n"); return -5; } return H->Elements[1]; } int IsEmpty(PriorityQueue H) { if (NULL == H) { printf("H is NULL!\n"); return -6; } if (0 == H->Size) { return 1; } else { return 0; } } int IsFull(PriorityQueue H) { if (NULL == H) { printf("H is NULL!\n"); return -7; } if (H->Capacity == H->Size) { return 1; } else { return 0; } } void Display(PriorityQueue H) { int i = 0; if (NULL == H) { printf("H is NULL!\n"); return; } for (i = 0; i <= H->Size; ++i) { printf("%d ", H->Elements[i]); } printf("\n"); return; } int main() { int flag = 0; ElementType MinElement = 0; PriorityQueue H = Initialize(100); Insert(13, H); Insert(21, H); Insert(16, H); Insert(24, H); Insert(31, H); Insert(19, H); Insert(68, H); Insert(65, H); Insert(26, H); Insert(32, H); Insert(14, H); Display(H); MinElement = FindMin(H); printf("min:%d\n", MinElement); MinElement = DeleteMin(H); printf("dele:%d\n", MinElement); MinElement = FindMin(H); printf("min:%d\n", MinElement); Display(H); Insert(13, H); Display(H); Insert(19, H); Display(H); MakeEmpty(H); flag = IsEmpty(H); if (flag) { printf("MakeEmpty and IsEmpty are ok, H is Empty!\n"); } else { printf("IsEmpty or MakEmpty are error!\n"); } Destory(H); return 0; }