樹的表示 Tree C C 實現

2021-09-10 09:26:44 字數 3145 閱讀 2533

請編寫乙個程式,輸出給定有根樹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時,稱為空樹。對於任意一棵非...