题目出处:
————————————————
二叉树也可以用数组来存储
给定一个数组
树的根节点的值储存在下标1
对于储存在下标n的节点,
他的左子节点和右子节点分别储存在下标2*n和2*n+1
并且我们用-1代表一个节点为空
给定一个数组存储的二叉树
试求从根节点到最小的叶子节点的路径
路径由节点的值组成
输入描述
输入一行为数组的内容
数组的每个元素都是正整数,元素间用空格分割
注意第一个元素即为根节点的值
即数组的第n元素对应下标n
下标0在树的表示中没有使用
所以我们省略了
输入的树最多为7层
输出描述
输出从根节点到最小叶子节点的路径上各个节点的值
由空格分割
用例保证最小叶子节点只有一个
例子
输入
3 5 7 -1 -1 2 4
输出
3 7 2
例子
输入
5 9 8 -1 -1 7 -1 -1 -1 -1 -1 6
输出
5 8 7 6
===============================================================
======================忧伤的分割线===============================
解题思路:
求出所有叶子节点中最小值,然后根据叶子结点下标即可推出父节点直到根节点
叶子结点条件:a[i] != -1 && a[2 * i] = -1 && a[2 * i + 1] = -1
或者 a[i] != -1 && 2 * i 超出总的节点数,比如用例1中节点2和节点4已经是叶子节点
找出最小叶子结点下标a[6] = 2 父节点a[6/2]=7 父节点(根节点)a[6/2/2] = 3
结果3 7 2
source code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i;
int min_pos = 0;
int min = 0x0fffffff;
int count = 1; /* 根节点从下标1开始 */
int a[128] = {0};
int res[128] = {0}; /* 记录路径 */
printf("input int array:\n");
while (scanf("%d", &a[count]) != EOF) {
count++;
}
/* 调试 */
printf("count = %d\n", count);
for (i = 1; i < count; i++) {
printf("%d ", a[i]);
}
printf("\n");
for (i = 1; i < count; i++) {
/* 找叶子节点:左右子节点为-1则是叶子结点,或者数组最后元素无子节点即是叶子结点 */
if ((a[i] != -1) && ((a[2 * i] == -1 && a[2 * i + 1] == -1) ||
(2 * i > count - 1))) {
/* 打印找到的叶子结点 */
printf("a[%d]:%d\n", i, a[i]);
if (a[i] < min) {
min = a[i];
min_pos = i;
}
}
}
count = 0;
while (min_pos != 0) {
res[count] = a[min_pos];
count++;
min_pos /= 2;
}
for (i = count - 1; i >= 0; i--) {
printf("%d ", res[i]);
}
printf("\n");
return 0;
}