37. 数组二叉树

85 阅读2分钟
题目描述:

二叉树也可以用数组来存储,给定一个数组,树的根节点的值存储在下标1,对于存储在下标N的节点,它的左子节点和右子节点分别存储在下标2N和2N+1,并且我们用值-1代表一个节点为空。

给定一个数组存储的二叉树,试求从根节点到最小的叶子节点的路径,路径由节点的值组成。

输入描述
  • 输入一行为数组的内容,数组的每个元素都是正整数,元素间用空格分隔。
  • 注意第一个元素即为根节点的值,即数组的第N个元素对应下标N,下标0在树的表示中没有使用,所以我们省略了。
  • 输入的树最多为7层。
输出描述

输出从根节点到最小叶子节点的路径上,各个节点的值,由空格分隔,用例保证最小叶子节点只有一个。

示例 1:

输入

3 5 7 -1 -1 2 4

输出

3 7 2

1

说明

最小叶子节点的路径为3 7 2

示例 2:

输入

5 9 8 -1 -1 7 -1 -1 -1 -1 -1 6

输出

5 8 7 6

说明

最小叶子节点的路径为5 8 7 6,注意数组仅存储至最后一个非空节点,故不包含节点“7”右子节点的-1

#include <iostream>
#include <vector>
#include <string>
using namespace std;

vector<int>tree;

bool isLeaf(int idx)
{
	// 叶子节点不为空
	if (tree[idx] == -1)
	{
		return false;
	}
	// 叶子节点没有左右子节点
	int lc = idx * 2 + 1;
	int rc = idx * 2 + 2;
	return (lc >= tree.size() || tree[lc] == -1) && (rc >= tree.size() || tree[rc] == -1);
}

int main()
{
	int num;
	while (cin >> num)
	{
		if (getchar() == '\n')
		{
			break;
		}
		tree.push_back(num);
	}

	int minLeafIdx = 60000;
	int minLeafVal = 60000;

	// 找出最小叶节点
	for (int i = 0; i < tree.size(); i++)
	{
		if (isLeaf(i) && tree[i] < minLeafVal)
		{
			minLeafIdx = i;
			minLeafVal = tree[i];
		}
	}

	string path = to_string(minLeafVal);

	int index = minLeafIdx;
	while (--index >= 0) // 从叶子找头节点
	{
		index /= 2;
		path = to_string(tree[index]) + " " + path;
	}	

	std::cout << path << std::endl;
	return 0;
}