运行结果正确
感觉堆还是比二叉搜索树容易实现

#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#include<malloc.h>
//构造结构堆
typedef struct node *heap;
struct node {
//这是一个数组
int *base;
int max;
int size;
};
//遍历这个堆
void tra(heap h){
for(int i=1;i<=h->size;i++){
printf("%d ",h->base[i]);
}
printf("\n");
}
//初始化(第一个节点是守门员)
heap init(int val){
heap h=(heap)malloc(sizeof(struct node));
h->base=(int*)malloc((val+1)*sizeof(int));
h->max=val;
h->size=0;
h->base[0]=-1;
return h;
}
//插入
heap insert(heap h,int val){
int i;
/*这里解释一下,
首先将size增加一位,用来空出一个位置,但是
不把val放进去,先判断这个空出的位置的父节点和val的大小关系
如果父节点要大,那就把父节点扔进空穴,此时原本父节点的位置就变成空穴了
此时如上述循环,不断把空穴上移,直到父节点终于比val要小了,就把
val扔进去,此时既满足完全二叉树,也满足根节点最大的条件*/
for(i=++(h->size);h->base[i/2]>val;i/=2){
h->base[i]=h->base[i/2];
}
h->base[i]=val;
return h;
}
//删除最小值
int del_min(heap h){
int last,min,child,i;
//首先把最小值和最后的位置保存起来,因为我们的
//size是要减一的,不保存的话,最后一个位子的元素一定会丢失
min=h->base[1];
last=h->base[h->size--];
/*解释一下,
首先因为根已经被取走了,留下一个空穴,多了一个没地方放的
last。先找根节点的左右儿子,抓一个小的,如果这个小儿子比last
要小,只能是小儿子往上顶,此时小儿子原来的位置就空了,继续往下比较,空穴不断下移
直到终于last比当前小儿子要小了,last填充空穴,此时已经没有空穴下移了,结束*/
for(i=1;i*2<=h->size;i=child){
child=i*2;
//找小儿子
//如果最后的儿子不等于size,因为是完全二叉树
//所以此时肯定有个右儿子,那就要比较了
//如果右儿子小的话,那就要选右儿子了。
if(child!=h->size&&(h->base[child]>h->base[child+1])){
child++;
}
//现在左右儿子已经判断出来了,就last比较就行了
if(h->base[child]<last) {
h->base[i]=h->base[child];
}
else{
//如果last较小,把last填进去,皆大欢喜,没有空穴了,那
//还循环什么
break;
}
}
//上述for一走完,肯定找到了那个可以插入last的空穴
h->base[i]=last;
return min;
}
int main(){
heap h=init(100);
insert(h,3);
insert(h,4);
insert(h,5);
insert(h,1);
tra(h);
del_min(h);
tra(h);
del_min(h);
tra(h);
del_min(h);
tra(h);
return 0;
}
这篇博客探讨了如何在C语言中实现堆的数据结构,包括插入和删除操作。作者提到,相对于二叉搜索树,实现堆的过程相对简单。
1595

被折叠的 条评论
为什么被折叠?



