所有原创文章转载请注明作者及链接// blackboycpp(AT)gmail.com// QQ群: 135202158 /******************************************************************** File: BinaryHeap.h Author: blackboy, blackboycpp@gmail.com Purpose: 优先队列,二叉堆、数组、C实现。 Created: 2011-04-14 Modified: 2011-04-14 16:53 *********************************************************************/ #ifndef __BINARY_HEAP_H__ #define __BINARY_HEAP_H__ typedef int ElementType; struct _HeapStruct; typedef struct _HeapStruct HeapStruct; typedef HeapStruct* PriorityQueue; struct _HeapStruct { int Capacity; int Size; ElementType* Vals; }; // PriorityQueue Create(int); void Destroy(PriorityQueue); void MakeEmpty(PriorityQueue); void Insert(ElementType, PriorityQueue); ElementType DeleteMin(PriorityQueue); ElementType FindMin(PriorityQueue); int IsEmpty(PriorityQueue); int IsFull(PriorityQueue); void InOrder(PriorityQueue, int); #endif #include <stdlib.h> #include <stdio.h> #include "BinaryHeap.h" // 需在位置0处设置一个标记元。它的值小于其他所有元素。 #define MinData -1; PriorityQueue Create(int maxElements) { PriorityQueue H = (PriorityQueue)malloc(sizeof(HeapStruct)); H->Capacity = maxElements; H->Size = 0; H->Vals = (ElementType*)malloc(sizeof(ElementType) * (maxElements+1)); H->Vals[0] = MinData; return H; } void Destroy(PriorityQueue H) { if(H == NULL) return; free(H->Vals); free(H); } void MakeEmpty(PriorityQueue H) { H->Size = 0; } void Insert(ElementType X, PriorityQueue H) { int i; if(IsFull(H)) return; // 向上过滤(percolate up) for(i = ++(H->Size); H->Vals[i/2] > X; i/=2) H->Vals[i] = H->Vals[i/2]; H->Vals[i] = X; } ElementType DeleteMin(PriorityQueue H) { int i, Child; ElementType MinVal, LastVal; if(IsEmpty(H)) return H->Vals[0]; MinVal = H->Vals[1]; LastVal = H->Vals[H->Size--]; // 注意Size-- for(i=1; i*2 <= H->Size; i=Child) { Child = i*2; if(Child != H->Size && H->Vals[Child+1] < H->Vals[Child] ) // ? Child++; // 向下过滤(Percolate down)一层 if(LastVal > H->Vals[Child]) H->Vals[i] = H->Vals[Child]; else break; } H->Vals[i] = LastVal; return MinVal; } ElementType FindMin(PriorityQueue H) { if(IsEmpty(H)) return H->Vals[0]; return H->Vals[1]; } int IsEmpty(PriorityQueue H) { return H->Size == 0; } int IsFull(PriorityQueue H) { return H->Size == H->Capacity; } void InOrder(PriorityQueue H, int i) { if(i > H->Size) return; InOrder(H, 2*i); printf("%d ", H->Vals[i]); InOrder(H, 2*i+1); } #include <stdio.h> #include <stdlib.h> #include "BinaryHeap.h" void PrintHeapArray(PriorityQueue H) { int i; // 依次输出堆内部数组中各元素 for(i=1; i<=H->Size; ++i) printf("%d ", H->Vals[i]); printf("/n"); } int main() { PriorityQueue queue; queue = Create(20); Insert(6, queue); /* 6 */ Insert(3, queue); /* 6 3 / -> / 3 6 */ Insert(7, queue); /* 3 / / 6 7 */ Insert(1, queue); /* 3 3 1 / / / / / / 6 7 -> 1 7 -> 3 7 / / / 1 6 6 */ Insert(4, queue); /* 1 / / 3 7 / / 6 4 */ Insert(2, queue); /* 1 1 / / / / 3 7 -> 3 2 / / / / / / 6 4 2 6 4 7 */ Insert(5, queue); /* 1 / / 3 2 / / / / 6 4 7 5 */ // 中序遍历 InOrder(queue, 1); printf("/n"); /* 输出: 6 3 4 1 7 2 5 */ PrintHeapArray(queue); /* 输出: 1 3 2 6 4 7 5 */ printf("FindMin: %d/n", FindMin(queue)); DeleteMin(queue); /* x <-Min 2 2 / / / / / / 3 2 -> 3 x -> 3 5 / / / / / / / / / / / 6 4 7 5 <-Last 6 4 7 5 6 4 7 */ PrintHeapArray(queue); /* 输出: 2 3 5 6 4 7 */ Destroy(queue); system("PAUSE"); return 0; }