UVA 712 S-Trees 解题报告

AC之后看了看网上的代码,我人麻了 o_O。

先上我的代码:

#include <iostream>                // Uva 712
#include <map>
using namespace std;
int nowdepth = 1;  // 遍历二叉树时 记录每时每刻走到的树的深度
int pace = -1;  // 输入01串,需要记录给下一片叶子赋为何值,pace为01串的下标
int init = 1;

typedef struct Tree
{
	struct Tree* LChild;
	struct Tree* RChild;
	char Ldata;   // 叶子的值为节点的属性
	char Rdata;   // 叶子的值为节点的属性
}TREE,*LPTREE;
LPTREE root;

LPTREE CreateNode()
{
	LPTREE node = (LPTREE)malloc(sizeof(TREE));
	return node;
}

void BuildTree(LPTREE &node,int depth, string& data)  //建树
{
	node = CreateNode();
	if (nowdepth == depth)   //若到达叶子
	{
		node->Ldata = data[++pace];
		node->Rdata = data[++pace];
		node->LChild = NULL;
		node->RChild = NULL;
		nowdepth -= 1;      //因为要返回,所以nowdepth减1
		return;
	}
	nowdepth++;
	BuildTree(node->LChild, depth, data);  
	if (nowdepth == depth)
	{
		node->Ldata = data[++pace];
		node->Rdata = data[++pace];
		node->LChild = NULL;
		node->RChild = NULL;
		nowdepth -= 1;     //因为要返回,所以nowdepth减1
		return;
	}
	nowdepth++;
	BuildTree(node->RChild, depth, data); 
	nowdepth--;      //因为要返回,所以nowdepth减1
}
   
char Search(int depth, LPTREE node, map<int,char>&lyb, string order)   // 查询操作
{
	int init;
	for (init = 1; init < depth; init++)  // 利用for循环遍历,遇0左拐,遇1右拐
	{
		if (lyb[init] == '0')
			node = node->LChild;
		else if (lyb[init] == '1')
			node = node->RChild;
	}        // 因为depth-1层之后没有子节点,所以只循环depth-1次
	if (lyb[init] == '0')  
		return node->Ldata;
	else if (lyb[init] == '1')
		return node->Rdata;
}

void Remove_Tree(LPTREE root) // 避免内存泄露
{
	if (root==NULL)
		return;
	Remove_Tree(root->LChild);
	Remove_Tree(root->RChild);
	delete root;
}
int main()
{
	int depth, num, kase = 1;
	while (cin >> depth && depth)
	{
		pace = -1;
		nowdepth = 1;
		map<int, char> lyb;
		string order, data, answer;
		data.clear();
		for (int i = 0; i < depth; i ++) //输入二叉树的结点标号顺序如x3,x1,x2
		{
			string orr;
			cin >> orr;
			order += orr[1];
		}
		cin >> data >> num ; // 输入01串、查询总数
		BuildTree(root, depth, data); // 初始化树,并给叶子赋值

		for (int i = 0; i < num; i++)
		{
			if(!i)
				printf("S-Tree #%d:\n", kase++);
			string str;
			cin >> str;  //查询串
			for (int i = 0; i < depth; i++)    // 建立map映射
				lyb[i + 1] = str[order[i] - '0' - 1];	
			answer += Search(depth, root, lyb, order);  // 在二叉树内查询,返回一个字符
			lyb.clear();
		}
		cout << answer << endl <<endl;
		Remove_Tree(root);
	}
}

题目大意:

        输入多组样例。

        每组样例第一行:二叉树深度depth;第二行:二叉树每层的标号order;第三行:2^depth个数字(即01串);第四行:输入查询总数n; 接下来n行:每行为长度为depth的01串。

        输出查询到的值。

我的分析:

        按部就班的解决问题。我就首先建立二叉树,并为叶子赋值。

        然后查询时,因为输入的二叉树各层顺序不同(可能x1,x2,x3或者x3,x1,x2等等),而输入的查询样例是按顺序的,即对应关系时错乱的,所以在查询的时候,要先理清二叉树索引的顺序。我的解决方法是建立映射关系map,将树的节点顺序(order)和01串查询样例(str)联系起来,方便查询。

        程序结束时销毁二叉树。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Jeffrey.pace

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

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

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

打赏作者

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

抵扣说明:

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

余额充值