問題描述:對樹中結點按層序列表是指先列樹根,然後從左到右一次列出所有深度爲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;
}