这个题比较简单,就是用数组建立一个堆,这个堆也是个完全二叉树,所以满足性质:
从1开始的数组中父结点的下标是子结点下标的
i
n
t
(
i
/
2
)
int(i/2)
int(i/2)
主要操作:
-
代码中最主要的步骤就是在堆中插入一个元素:
为了满足完全二叉树,我们需要把新的结点先放到最后一个位置,
为了满足最小堆的建立,我们把新的结点进行与父结点比较并调整 -
我们在与父结点比较时,因为数组的有效结点是从1开始的,我们应该避免与数组的0元素比较
我们可以在0这个下标放一个特别特别小的数
使得在Insert这个操作中,我们不需要单独设置一个条件避免与H[0]比较
而是直接不让H[0]满足H[i / 2] > X这个条件
#include <stdio.h>
#include <stdlib.h>
int H[1001], size;
void Creat() {
size = 0;
H[0] = -10001; //设置岗哨,使得每次遍历树的父节点的结束条件简单
}
//构建最小堆
void Insert(int X) { //先放到最后一个位置(为了满足完全二叉树),之后再调整(为了满足堆)
int i;
for (i = ++size; H[i / 2] > X; i /= 2) {
H[i] = H[i / 2]; //当父结点比X大的时候,把X放在父结点位置上 父结点的下到子结点
}
H[i] = X;
}
int main() {
int n, m, x, i, j;
scanf("%d %d", &n, &m);
Creat();
for (i = 0; i < n; i++) {
scanf("%d", &x);
Insert(x);
}
for (i = 0; i < m; i++) {
scanf("%d", &j);
printf("%d", H[j]);
while (j > 1) {
j /= 2;
printf(" %d", H[j]);
}
printf("\n");
}
return 0;
}