1. 程式人生 > >有根樹的表達_左子右兄弟表示法

有根樹的表達_左子右兄弟表示法

這是<<挑戰程式設計競賽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; }