这是<<挑战程序设计竞赛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;
}