有根樹的表達_左子右兄弟表示法
阿新 • • 發佈:2019-01-10
這是<<挑戰程式設計競賽2>>上的一節, 介紹了用左子右兄弟的方法儲存一棵有根樹.
用遞迴的方法求出所有結點的深度, 複雜度為O(n)
或者是單獨求出一個結點的深度(遞迴或是迴圈)
以及如何遍歷一個結點的所有子結點
#include <bits/stdc++.h>
using namespace std;
#define MAX 1005
struct Node {
int p, l, r;
} T[MAX];
int D[MAX], n; //陣列D儲存樹所有節點的深度
void getDepth(int u, int d) //u代表結點編號,d代表結點深度
{
D[u] = d;
if(T[u].l != -1) getDepth(T[u].l, d+1); //是兒子就增加深度
if(T[u].r != -1) getDepth(T[u].r, d); //是兄弟就不增加深度
}
void buildTree() //建立一棵有根樹
{
int x, y, k, t;
cin >> n;
for(int i = 0; i < n; ++i)
T[i].p = T[i].l = T[i].r = -1; //剛開始都是沒有的,初始化為-1
for(int i = 0; i < n; ++i) {
cin >> x >> k; //第x個結點,有k個兒子結點
for(int j = 0; j < k; ++j) {
cin >> y;
if(j == 0) T[x].l = y; //第一個結點,儲存為左子
else T[t].r = y; //其餘結點,儲存為上一個結點的右兄弟
t = y;
T[y].p = x; //所有節點都是x的兒子結點
}
}
int root = 0; //根節點編號
for(int i = 0; i < n; ++i)
if(T[i].p == -1) root = i;
getDepth(root, 0); //得到深度資料
}
void printSon(int u) //輸出兒子結點。從左子開始,迭代遍歷其右兄弟
{
if(T[u].l != -1) {
u = T[u].l;
cout << u;
while(T[u].r != -1) {
cout << ", "<< T[u].r;
u = T[u].r;
}
}
}
void printData() //輸出資料
{
for(int i = 0; i < n; ++i) {
cout << "node " << i << ": parent = " << T[i].p << ", depth = " << D[i] << ", ";
if(T[i].p == -1) cout << "root, [";
else if(T[i].l == -1) cout << "leaf, [";
else cout << "internal node, [";
printSon(i);
cout << ']';
cout << endl;
}
}
int oneDepth(int u) //獲得一個節點的深度
{
if(T[u].p != -1) return oneDepth(T[u].p) + 1;
else return 0;
}
int main()
{
buildTree();
printData();
cout << "結點5的深度為:" << oneDepth(5) << endl;
cout << "結點9的深度為:" << oneDepth(9) << endl;
}