UVA-712-S-Trees-完全二叉树

注意:本文只给出作者认为必要的知识点并且可能存在疏漏。


一、题目大意

  给一颗 深度n完全二叉树 ,每一层的 非终端结点 都有特定值 Xi(1、0),从根结点开始向下走,若当前 Xi 的值为1则向右子树深入,否则向左子树深入,输出到达 叶子结点 的值。其有 2n 个叶子结点,叶子结点的值按序给出,但 Xi 的排列为无序。原题链接


二、理论基础

1. 二叉树

1.1 二叉树的定义

  一种树型结构,它的特点是每个结点至多只有两颗子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树的左右之分,其次序不能任意颠倒。1

1.2 二叉树的性质

  1. 在二叉树的第 i 层上至多有 2i-1 个结点。 i ≥ 0 \textcolor{#FF0000}{i \geq 0} i0
  2. 深度为 k 的二叉树最大结点数为 ∑ i = 1 k = 2 k − 1 , k ≥ 1 {\sum_{i=1}^{k}=2^k-1}, \textcolor{#FF0000}{k \geq 1} i=1k=2k1,k1
  3. 对于任意二叉树,若其终端结点数为 x,度为2的结点数为 y,则 x = y + 1 x=y+1 x=y+1

2. 满二叉树

  一颗深度为 k 且有 2k-1 个结点的二叉树,每一层上的结点数都是最大结点数。对满二叉树的结点进行连续编号(一般从1开始编号),约定编号从根结点起,自上而下,从左向右。1

3. 完全二叉树

3.1 完全二叉树的定义

  一颗深度为 k 的二叉树并对其结点进行编号,若其与深度同为 k满二叉树的编号一一对应(编号从1到n且连续)则为完全二叉树。满二叉树一定是完全二叉树,完全二叉树是满二叉树按序删去末尾结点的产物。

3.2 完全二叉树的性质 本题重点

  1. 对于任意非终端结点 i,若其有左孩子,则必为结点 2 × i 2\times i 2×i
  2. 对于任意非终端结点 i,若其有右孩子,则必为结点 2 × i + 1 2\times i +1 2×i+1

三、解题思路

  按完全二叉树的结点编号规律进行递推即可计算出叶子结点的编号,注意本题深度从0开始并且 Xi 的排列为无序。


四、参考代码

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
#define maxn 129
#define INF 0x3f3f3f
typedef long long ll;


int main() {
	int n, order[7], Case = 1, T, base;
	char c[3],  stemp[8], s[maxn];
	vector<int> result;
	result.reserve(maxn * 4);//优化速度
	ios::sync_with_stdio();
	cin.tie(0);
	cout.tie(0);

	while (cin >> n && n) {
		result.clear();//清空
		base = 1 << n;
		for (int i = 0; i < n; ++i) {
			cin >> c;
			order[i] = c[1] - '1';
		}
		cin >> s >> T;
		for (int i = 0; i < T; ++i) {
			int itemp = 1;
			cin >> stemp;
			for (int j = 0; j < n; ++j) {
				itemp <<= 1;
				itemp += stemp[order[j]] == '0' ? 0 : 1;//右孩子加1
			}
			result.push_back(s[itemp - base] - '0');//itemp为叶子结点的编号
		}
		cout << "S-Tree #" << Case++ << ':' << endl;
		for (int i = 0; i < result.size(); ++i)
			cout << result[i];
		putchar('\n');
		putchar('\n');
	}
	return 0;
}

  1. 数据结构(C语言版) [专著] / 严蔚敏,吴伟民编著 ↩︎ ↩︎

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

✷大傻瓜✷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值