题如上图
思路:
①用数组来代替堆的建立
②动态建堆(一开始直接往数组中插入全部的元素,然后从第一个非叶子结点逐个与其左右结点进行替换,发现存在漏洞,当你从下往上进行完一轮排查替换后,新的堆并不一定符合堆的定义,发现是因为刚开始的元素本就是乱序,并没有结点之间的大小关系,所以从顶上淘汰下来的元素并不一定就与底部元素构成根结点大于左右结点的关系,所以只能动态建堆)
①的实现:
因为题目所给的数据是从一开始,所以将数组的首元素置为可能出现的最小值,从一开始输入元素
②的实现:
假设当前结点为i,那么它的根结点就为i/2
所以每输入一个结点,就将它与其根结点进行大小比较
如果小,进行结点值的替换,并i/=2继续排查直到根结点为止
如果符合,退出循环,将新结点赋值为element
#include<stdio.h>
#define Max 1001
#define Min -10001
int heap[Max];
int size;
void Create()//初始化堆数组
{
heap[0] = Min;
size = 0;
}
void Insert(int *h,int element)
{
int i;
/*动态建堆*/
for(i = ++size;element < h[i/2];i/=2){
h[i] = h[i/2];
}
h[i] = element;
}
int main()
{
int N,M;
scanf("%d%d",&N,&M);
Create();
int i;
for(i = 1;i <= N;i++){
scanf("%d",&heap[i]);
Insert(heap,heap[i]);
}
while(M){
scanf("%d",&i);
printf("%d",heap[i]);
while(i/=2)
printf(" %d",heap[i]);
if(--M)
printf("\n");
}
}