题目链接:http://dsalgo.openjudge.cn/tree/7/
借着一题来总结一下多叉树和二叉树的关系:多叉树和二叉树是等价的。
如果使用在一个节点内保存的是指向第一个儿子(为了方便加上最后一个儿子也是极好的)和兄弟的指针的方法维护一棵树,那么棵树是多叉树还是二叉树全在乎遍历的方式。如图所示:
将右边的兄弟作为儿子节点来看,这就是一颗二叉树(左儿子右兄弟表示法)
对于这道题,我有两个思路:
1. 不建树:多叉树的深度=在整个树的输入中d的个数超过u的个数最大的那个值,这个统计一下或递归计算一下就可以了;对于相应的二叉树的深度,观察可知儿子节点的深度=父结点深度+这是第几个儿子节点,由此递归即可,递归基是没有儿子节点的情况。
2. 建树:每个节点保留父节点指针,兄弟节点指针,第一个和最后一个儿子节点指针。遇到’d’就添加儿子节点,遇到’u’就返回到父节点。得到树后,两种高度都可以用深度优先(在这里相当于先序遍历)来求得,区别在于把右兄弟当作什么角色。
我在这里只实现了思路1.
#include <cstdio>
const int MAXN = 20010;
int Bheight, Mheight;
void recursiveCount(char * str, int& ind, int Blevel, int Mlevel)
{
int son = 0;
while('d' == str[ind]) {
++ind;
++son;
recursiveCount(str, ind, Blevel+1, Mlevel+son);
}
//这里str[ind] = 'u'要返回上一层,相当于回到父节点处
++ind;
Bheight = Blevel>Bheight?Blevel:Bheight;
Mheight = Mlevel>Mheight?Mlevel:Mheight;
}
int main()
{
char str[MAXN];
int tree = 0;
int ind;
while(gets(str) && str[0] != '#') {
Bheight = 0;
Mheight = 0;
++tree;
ind = 0;
recursiveCount(str, ind, 0, 0);
printf("Tree %d: %d => %d\n", tree, Bheight, Mheight);
}
return 0;
}