问题描述:对树中结点按层序列表是指先列树根,然后从左到右一次列出所有深度为1的节点,再从做到右地列出深度为2的节点,等等。层序列表问题要求对一颗给定的二叉树按层序列表。
数据输入:第一行为一个整数n,表示给定的二叉树有n个顶点。接下来的n行中,每行有3个整数a,b,c 分别表示编号为a的节点的左儿子b和右儿子c。0表示结点为空。
5
1 4 2
4 3 0
2 5 0
3 0 0
5 0 0
数据输出:
1 4 2 3 5
就它这个数据形式,我觉得实际去建立一颗链表二叉树会相当麻烦,因为给出的结点关系并没有说明是自上而下的(虽然测试样例是这样)。虽然依旧使用结构体数组存储结点,但是左右儿子关系是使用下标存储。假设当前结点为t,那么t->left就是结点t->left的下标,通过node[t->left]就能访问该结点了。
以上问题清晰之后,关键就在于寻找根结点。根节点有一个重要的特点就是它不可能是这棵树任一结点的儿子结点,因此在输入时b和c中没有出现的下标即为根节点。
最后,层次遍历依旧是用队列去做,这个没有什么好说的了。
#include <iostream>
#include <queue>
using namespace std;
typedef struct{
int data;
int left, right;
}TreeNode;
int findRoot(int find[], int n)
{
for(int i = 1; i <= n; ++i)
if( find[i] == 0 )
return i;
return -1;
}
int main()
{
int i, n;
int a, b, c;
while( cin >> n )
{
int find[n+1] = {0};
TreeNode node[n+1];
for(i = 1; i <= n; ++i){
cin >> a >> b >> c;
node[a].data = a;
node[a].left = b;
node[a].right = c;
find[b] = find[c] = 1; // 所有儿子节点标记为 1
}
// 根节点不是任一结点的儿子节点
int root = findRoot(find, n);
if( root == -1 ){
cerr << "数据有误!请重新输入!" << endl;
continue;
}
queue<TreeNode> que; // 队列实现层次遍历
que.push(node[root]); // 根节点入队
while( !que.empty() ){
TreeNode t = que.front();
que.pop();
cout << t.data << " "; // visit()
if( t.left != 0 )
que.push(node[t.left]);
if( t.right!= 0 )
que.push(node[t.right]);
}
cout << "-----END-----" << endl;
}
return 0;
}