6 7 trees_on_the_level_uva122) - nuaazdh/acm GitHub Wiki
##例题6-7 二叉树层次遍历(Trees on the level UVa122)
###问题
按(n,s)
格式给定一个二叉树,其中n为二叉树节点的值,s为该节点相对于根节点的位置,L表示左子树,R表示右子树, LL表示左子树的左子结点,以此类推。()
标识当前二叉树结束, 程序的输入以EOF
结束。二叉树的结点个数不大于256。 输出二叉树的层次遍历结果,如果存在未赋值的结点,或者结点的值重复出现,输出not complete。
样例输入
(11,LL) (7,LLL) (8,R)
(5,) (4,L) (13,RL) (2,LLR) (1,RRR) (4,RR) ()
(3,L) (4,R) ()
样例输出
5 4 8 11 13 4 7 2 1
not complete
###分析
二叉树的层次遍历非常简单,使用队列来实现即可。如何存储这个二叉树?数组?因为此题二叉树不保证完全二叉树,数组存储太大了(比如只有左子树的情况)。因此还是要动态申请空间。
二叉树的结点结构体的定义,可以参照leetcode上的常见定义方式:
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
###code in C++
#include <iostream>
#include <vector>
struct btnode {
int val;
btnode *left;
btnode *right;
btnode(int v) : val(v), left(NULL), right(NULL) { }
};
void tree_on_level(btnode *root) {
std::vector<btnode *> tree;
bool flag = true;
tree.push_back(root);
int i = 0;
while (1) {
if (i > tree.size() - 1) {
break;
}
if (tree[i] == NULL) {
flag = false;
break;
}
if (tree[i]->val == 0) {
flag = false;
break;
}
// std::cout<<"root: "<<tree[i]->val;
if (tree[i]->left) {
tree.push_back(tree[i]->left);
// std::cout<<"\tleft:"<<tree[i]->left->val;
}
if (tree[i]->right) {
tree.push_back(tree[i]->right);
// std::cout<<"\tright:"<<tree[i]->right->val<<"\n";
}
++i;
}
if (flag) {
for (i = 0; i < tree.size(); ++i) {
if (i) std::cout << " ";
std::cout << tree[i]->val;
delete tree[i];
}
} else {
std::cout << "not complete";
}
std::cout << "\n";
}
int main() {
std::string line;
while (std::cin >> line) {
btnode *root = new btnode(0);
bool valid = true;
do {
int val = 0;
int i;
for (i = 1; i < line.length() && line[i] != ','; ++i) {
val = val * 10 + (line[i] - '0');
}
if (val == 0) { valid = false; }
btnode *ptr = root;
for (++i; i < line.length(); ++i) {
if (line[i] == 'L') {
if (ptr->left == NULL) {
ptr->left = new btnode(0);
}
ptr = ptr->left;
} else if (line[i] == 'R') {
if (ptr->right == NULL) {
ptr->right = new btnode(0);
}
ptr = ptr->right;
} else {
}
}
if (ptr->val != 0) {
valid = false;
}
ptr->val = val;
} while (std::cin >> line && line != "()");
if (valid) tree_on_level(root);
else {
std::cout << "not complete\n";
}
}
}
###点评
- 注意在
do{}while
中不能使用局部变量给 node 的结点赋值,因为循环内的变量作用域有限; - 使用了个技巧,不在需要queue,而是vector实现了queue的功能;