堆实际上是二叉堆,二叉堆是优先队列的一种实现方式,最常用的使用数组来实现。
堆具有如下两个性质:结构性和堆序性
1、结构性
堆是一个被完全填满的二叉树(底层有例外)
2、堆序性
子节点元素值都小于父节点元素值
既然堆是优先队列就满足priority queue的基本性质,Insert和DeletMin
堆的初始化
typedef int ElementType;
typedef struct HeapStruct * HeapNode;
typedef HeapNode PriorityHeap;
struct HeapStruct{
int capacity;
int size;
ElementType *element;
};
其中memset防止分配到的空间,存在脏数据
MaxElement+1,如果是char类型,后面会有一个结束符
static PriorityHeap Initialize(int MaxElement)
{
PriorityHeap heap = NULL;
heap =(PriorityHeap)malloc(sizeof(*heap));
if(heap==NULL){
fprintf(stderr, "there is no space\n");
return NULL;
}
memset(heap,0,sizeof(*heap));
heap->element = (ElementType *)malloc((MaxElement+1)*sizeof(ElementType));
if(heap->element==NULL){
fprintf(stderr, "there is no space\n");
return NULL;
}
memset(heap->element, 0, sizeof(ElementType)*(MaxElement+1));
heap->capacity = MaxElement;
heap->size = 0;
return heap;
}
堆的建立==插入,这里就类似将数据插入队列中
static void Insert(ElementType x, PriorityHeap heap)
{
int i = 0;
//size的值是在这里发生变化的
//printf("++heap->size is %d\n", ++heap->size);
//printf("heap->size++ is %d\n", heap->size++);
//printf("x is %d\n", x);
for(i=++heap->size;heap->element[i/2]>x;i/=2){
//printf("before: heap->size is %d\t heap->element[%d] is %d\n", heap->size, i, heap->element[i]);
heap->element[i] = heap->element[i/2];
//printf("after: heap->size is %d\t heap->element[%d] is %d\n", heap->size, i, heap->element[i]);
}
heap->element[i] = x;
return ;
}
堆的遍历
PriorityHeap heap = NULL;
heap = Initialize(30);
int ar[] = { 32, 21, 16, 24, 31, 19, 68, 65, 26, 13 };
int i = 0;
for ( i = 0; i < sizeof(ar)/sizeof(ar[0]); i++ ){
Insert( ar[i], heap);
}
for(i=0;isize;i++){
printf("%d\t", heap->element[i]);
}
输出的数据如下:
0 13 16 19 26 24 21 68 65 32
实际上就满足了堆的结构性
查找删除最小值
static ElementType DeleteMin(PriorityHeap heap)
{
ElementType min = heap->element[1];
//printf("min is %d\n", min);
ElementType last = heap->element[heap->size--];
//printf("last is %d\n", last);
//printf("heap->size is %d\n", heap->size);
int i=0;
int child=0;
for(i=1; child*2<=heap->size;i=child){
child=i*2;
if(child<=heap->size&&heap->element[child+1]element[child]){
child++;
}
if(heap->element[child]element[i] = heap->element[child];
}else{
break;
}
}
//printf("i is %d\n", i);
heap->element[i] = last;
return min;
}
mian函数中的调用如下:
int main()
{
PriorityHeap heap = NULL;
heap = Initialize(30);
int ar[] = { 32, 21, 16, 24};
int i = 0;
for ( i = 0; i < sizeof(ar)/sizeof(ar[0]); i++ ){
Insert( ar[i], heap);
}
for(i=0;ielement[i]);
}
printf("\n");
for(i=0;i
输出结果为:
$ ./a.exe
0 16 24 21 32
16
21
24
32
32