請編寫乙個程式,輸出給定有根樹t中各節點u的資訊,資訊內容如下:
u的結點編號
u的結點種類(根、內部節點、葉)
u的父節點編號
u的子結點列表
u的深度
這裡我們設給定樹擁有n個結點,編號分別為0至n - 1。
輸入:第1行輸入結點的個數n。接下來n行按照下述格式輸入各結點的資訊,每個結點佔一行。
id k c1 c2 … ck
id為結點的編號,k為度。c1 c2 … ck為第1個子結點到第k個子結點的編號。
輸出:請按下述格式輸出結點的資訊。結點資訊按編號公升序排列。
node id: parent = p, depth = d, type, [c1, …, ck]
p代表父節點的編號。不存在父節點時輸出-1。d表示結點的深度。type表示結點的型別,從roor(根)、internal node(內部結點)、leaf(葉)三個字串中選擇其一。
c1…ck是子結點列表。這裡我們將給定樹視為有序樹,請按照輸入的順序輸出。相鄰資訊用逗號和空格隔開。
限制:
1 ≤ n ≤ 100000
結點的深度不超過20。
13
0 3 1 4 10
1 2 2 3
2 03 0
4 3 5 6 7
5 06 0
7 2 8 9
8 09 0
10 2 11 12
11 0
12 0
node 0: parent = -1, depth = 0, root, [1, 4, 10]
node 1: parent = 0, depth = 1, internal node, [2, 3]
node 2: parent = 1, depth = 2, leaf,
node 3: parent = 1, depth = 2, leaf,
node 4: parent = 0, depth = 1, internal node, [5, 6, 7]
node 5: parent = 4, depth = 2, leaf,
node 6: parent = 4, depth = 2, leaf,
node 7: parent = 4, depth = 2, internal node, [8, 9]
node 8: parent = 7, depth = 3, leaf,
node 9: parent = 7, depth = 3, leaf,
node 10: parent = 0, depth = 1, internal node, [11, 12]
node 11: parent = 10, depth = 2, leaf,
node 12: parent = 10, depth = 2, leaf,
首先我們要考慮如何儲存輸入的有根樹。本題中,樹在輸入完成後結點數不再變化,所以可以利用左子右兄弟表示法(left-child right-sibling representation)來表示樹。左子右兄弟表示法中的各節點具有以下資訊。
結點u的父結點
結點u的最左側子結點
結點u右側緊鄰的兄弟結點
左子右兄弟表示法的實現
struct node;
struct node t[max];
//或者
int parent[max], left[max], right[max];
引用u.parent即可知道各結點u的父結點。不存在父結點的就是根。另外,不存在u.left的結點為葉(leaf),不存在u.right的結點為最右側子結點。為表示不存在父結點、左子結點、右兄弟結點的情況,我們將值nil用作乙個特殊的結點編號。此時要保證nil不作為一般結點編號使用。
各結點的深度可通過下述演算法求得。
getdepth(u)
d = 0
while t[u].right != nil
u = t[u]].parent
d++return d
求結點u的深度時,需要從u出發逐一尋找父結點,統計u到根之間總共經過的邊數。這裡我們將根的父結點設為nil(-1),從而與其他節點區分開。
另外,使用下述遞迴性質的演算法可以更快求出樹中所有結點的深度。
setdepth(u, p)
d[u] = p
if t[u].right != nil
setdepth(t[u].right, p)
if t[u].left != nil
setdepth(t[u].left, p + 1)
上述演算法會遞迴地計算右側兄弟結點以及最左側子結點的深度。這裡的t通過左子右兄弟表示法實現,如果當前結點存在右側兄弟結點,則不改變深度p直接進行遞迴呼叫,如果存在最左側子結點,則先將深度加1再進行遞迴呼叫。
結點u的子結點列表從u的左側子結點開始按順序輸出,直到當前子結點不存在右側兄弟結點為止。
printchildren(u)
c = t[u].left
while c != nil
print c
c = t[c].right
#include
using namespace std;
#define max 100005
#define nil -1
struct node
;node t[max]
;int n, d[max]
;void
print
(int u)
cout<<
"]"<}//遞迴地求深度
intrec
(int u,
int p)
intmain()
}for
(i =
0; i < n; i++
)rec
(r,0);
for(i =
0; i < n; i++
)print
(i);
return0;
}
樹 孩子兄弟表示法的實現
樹狀圖是一種資料結構,它是由n n 1 個有限節點組成乙個具有層次關係的集合。把它叫做 樹 是因為它看起來像一棵倒掛的樹,也就是說它是根朝上,而葉朝下的。它具有以下的特點 每個節點有零個或多個子節點 沒有父節點的節點稱為根節點 每乙個非根節點有且只有乙個父節點 除了根節點外,每個子節點可以分為多個不...
4 樹 樹的表示
根據某個給定關鍵字k,從集合r中找出關鍵字與k相同的記錄 int sequentialsearch statictable tbl,elementtype k return 1 順序查詢演算法的時間複雜度為o n 假設n個資料元素的關鍵字滿足有序 比如 小到大 k 1 le k 2 le le k ...
樹和樹的表示
part1 樹 在現實生活中,有很多具有層次的關係。層次管理具有很高的效率。在計算機中也是一樣,樹就實現了計算機中的層次,在查詢修改資訊方面提供了很大的方便。之前在學習離散數學時已經對樹有了了解,所以這裡理解起來很容易。樹的定義 n n 0 個結點構成的有限集合。當n 0時,稱為空樹。對於任意一棵非...