uva122解题报告

题意大致就是给你一棵树,然后你用层序遍历。每个节点的给出通过一个组合,(value, pos)pos是由LR组合而成。L代表一次左儿子,R为一次右儿子。输出时需要注意判断给的结点是否完整和重复。


解题思路: 1.不能用数组存储满二叉树。256个结点如果排成一个偏左树,那数组将非常非常大。行不通。所以用数组存储每一个输入的结点。

2. 总共4个数组 left数组存放当前结点的左儿子的结点在数组中的下标 right数组相对。 have_value 用来判断此结点是否有值(因为,我们输入结点时,如果他的父节点为空,则创建一个父节点,再往下走。但此时新的父节点是无值得)。 value数组存放值。


代码如下:

#include <iostream>
#include <cstring>
#include <queue>

using namespace std;

const int MAXN = 3000;
const int maxn = 100000;

int lef[MAXN],righ[MAXN],have_value[MAXN], value[MAXN];
char s[maxn] = "";

const int root =1;
int nCnt = 0;
bool isFailed = false; // 用来标记输入是否有重复 

void newTree() {
	lef[root] =0;
	righ[root] = 0;
	have_value[root] = false;
	isFailed = false;
	value[root] = 0;
	nCnt = 1;
}

int newNode() {
	int index = ++nCnt;
	lef[index] = righ[index] = 0;
	have_value[index] = false;
	return index;
}

void addNode(int val, char *pStr) {
	int index = root;
	for (int i =0;i<strlen(pStr);++i) {
		if (pStr[i] == 'L') {
			if (lef[index] == 0)
				lef[index] = newNode();
			index = lef[index];
		} else if (pStr[i] == 'R') {
			if (righ[index] == 0)
				righ[index] = newNode();
			index = righ[index];
		}
	}
	if(have_value[index])
		isFailed = true;
	value[index] = val;
	have_value[index] = true;	
}

bool bfs(vector<int> &ans/*存放结果*/) {
	
	queue<int> q; // int用来存放元素的下标
	ans.clear();
	q.push(root);
	while (!q.empty()) {
		int index = q.front();q.pop();
		if (!have_value[index]) 
			return false;
		ans.push_back(value[index]);
		if (lef[index]) q.push(lef[index]);
		if (righ[index]) q.push(righ[index]); 
	}
	return true;
}


bool read() {
	
	newTree();
	while(true) {
		if	(scanf("%s", s) != 1)
			return false;
		if (!strcmp(s, "()"))
			break;
		int val;
		sscanf(&s[1], "%d", &val);
		addNode(val, strchr(s, ','));
	}
	return true;
}

int main() {
	
	while (true) {
		if (!read())
			break;
		if (isFailed) {
			cout<<"not complete"<<endl;
			continue;
		} 
		
		vector<int> ans;
		if (!bfs(ans)) 
			cout<<"not complete"<<endl;
		else {
			for (vector<int>::iterator i = ans.begin(); i!= ans.end();) {
				cout<< *i;
				if (++i != ans.end())
					cout<<" ";
			}	
			cout<<endl; 
		}
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值