二叉堆的抽象数据类型:
1 #ifndef _BinHeap_H 2 #define ElementType int 3 #define MinElement -1000 4 struct HeapStruct; 5 typedef struct HeapStruct *PriorityQueue; //结构体指针 6 PriorityQueue Initialize(int MaxElements); //初始化一个二叉堆 7 void Destroy(PriorityQueue H); //销毁二叉堆的操作 8 void MakeEmpty(PriorityQueue H); //置空一个二叉堆的操作 9 void Insert(ElementType X, PriorityQueue H); //插入操作 10 ElementType DeleteMin(PriorityQueue H); //删除最小元的操作 11 ElementType FindMin(PriorityQueue H); //找到最小元的操作 12 int IsEmpty(PriorityQueue H); //判断二叉堆是否为空的操作 13 int IsFull(PriorityQueue H, int MaxElement); //判断二叉堆是否已满的操作 14 PriorityQueue CreateHeap(ElementType a[], PriorityQueue H, int n);//利用数组创建二叉堆的操作 15 void BuildHeap(ElementType a[], PriorityQueue H, int N); //利用数组创建二叉堆的操作 16 #endif 17 18 struct HeapStruct{ 19 int Capacity; 20 int size; 21 ElementType *Elements; 22 };
二叉堆的一般操作实现:
#include <iostream> #include <stdio.h> #include <stdlib.h> #include "Heap.h" using namespace std; //初始化一个二叉堆 PriorityQueue Initialize(int MaxElements){ PriorityQueue H = (PriorityQueue)malloc(sizeof(struct HeapStruct)); H->Capacity = MinElement; H->size = 0; H->Elements = (ElementType *)malloc(MaxElements*sizeof(ElementType)); return H; } //插入操作,主要的动作是——上滤 void Insert(ElementType X, PriorityQueue H){ int i; for(i = ++H->size; i / 2 >= 1; i /= 2){ if(H->Elements[i / 2] > X){ H->Elements[i] = H->Elements[i/2]; } else{ break; } } H->Elements[i] = X; } //用一个数组创建一个二叉堆,通过反复调用Insert()操作来保证新的元素进入时的堆序性 PriorityQueue CreateHeap(ElementType a[],PriorityQueue H, int n){ for (int i = 0; i < n; i++) { Insert(a[i], H); } } //输出整个二叉堆的所有元素,输出顺序是Elements数组的顺序 void PrintBinHeap(PriorityQueue H){ printf("优先队列为:"); for (int i = 1; i <= H->size; i++) { printf("\t%d", H->Elements[i]); } printf("\n"); } //删除二叉堆堆顶的元素,即最小的那个元素;主要的操作是——下滤 ElementType DeleteMin(PriorityQueue H){ ElementType LastElement = H->Elements[H->size--]; ElementType MinElements = H->Elements[1]; int i, Child; for(i = 1; i * 2 <= H->size; i = Child){ Child = i * 2; if(Child != H->size && H->Elements[Child + 1] < H->Elements[Child]){ //判断某个结点是否只有一个孩子结点 Child++; } if(H->Elements[Child] < LastElement){ H->Elements[i] = H->Elements[Child]; } else{ break; } } H->Elements[i] = LastElement; return MinElements; } //销毁二叉堆 void Destroy(PriorityQueue H){ free(H->Elements); free(H); } //清空二叉堆,并返回一个空的二叉堆 void MakeEmpty(PriorityQueue H){ free(H->Elements); } //判断二叉堆是否为空 int IsEmpty(PriorityQueue H){ return H == NULL; } //判断二叉堆是否已满 int IsFull(PriorityQueue H, int MaxElement){ return H->size > MaxElement; } ElementType FindMin(PriorityQueue H){ return H->Elements[1]; } //利用数组创建二叉堆的操作,只需花费线性时间O(N) void PercolateDown(ElementType a[], int i, int N){ int Child, Element = a[i]; int k; for(k = i; k * 2 <= N; k = Child){ Child = k * 2; if(Child != N && a[Child+1] < a[Child]){ Child++; } if(Element > a[Child]){ a[k] = a[Child]; } else{ break; } } a[k] = Element; } void BuildHeap(ElementType a[], PriorityQueue H, int N){ for(int i = N/2; i > 0; i--){ PercolateDown(a, i, N); } for(int i = 1; i <= N; i++){ H->Elements[i] = a[i]; H->size++; } } void Election() int main(){ PriorityQueue H; int n; printf("请输入元素个数:\n"); scanf("%d", &n); ElementType a[n+1]; printf("请输入元素,以空格分隔:\n"); for(int i = 1; i <= n; i++){ scanf("%d", &a[i]); } H = Initialize(68); BuildHeap(a, H, n); PrintBinHeap(H); printf("%d", FindMin(H)); system("pause"); return 0; }