Time Limit: 1 Sec Memory Limit: 4 MB
Description
计算输入有序树的深度和有序树转化为二叉树之后树的深度。
Input
输入包含多组数据。每组数据第一行为一个整数n(2<=n<=30000)代表节点的数量,接下来n-1行,两个整数a、b代表a是b的父亲结点。
Output
输出当前树的深度和转化成二叉树之后的深度。
Sample Input
5
1 5
1 3
5 2
1 4
Sample Output
3 4
算法一 : 二叉链表
用孩子-兄弟表示法表示有序树和二叉树,这也就意味着直接用二叉树的形式表示有序树,只不过每个节点的两个指针不是左右孩子的指针,而是一个指向第一个孩子、另一个指向下一个兄弟。
有序树转二叉树在遍历的时候,操作不一样。
在形式上有序树存成了二叉树的样子,看的角度不同,就是有序树与二叉树的区别。
遍历一个存成二叉树形式的有序树的算法:
int depth_Tree(CSTree t)
{
if(t==NULL)
return 0;
int firstchild_depth = depth_Tree(t->firstchild);
int nextsibling_depth = depth_Tree(t->nextsibling);
return (firstchild_depth+1 > nextsibling_depth ? firstchild_depth+1 : nextsibling_depth);
}
完整程序: (OJ系统判断 TimeLimit Exceed)
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
typedef int ElemType;
typedef int Status;
///孩子-兄弟表示法
typedef struct CSNode
{
ElemType data;
struct CSNode *firstchild,*nextsibling;
} CSNode,*CSTree;
///初始化树
int Init_CSTree(CSTree &t)
{
t=NULL;
//static int maxn = 0;
return 0;
}
//查找数据元素
CSNode *Traverse(CSTree t,int x)
{
//查找数据元素x是否在二叉树root中
//查找到则返回该节点指针,未查找到则返回空指针
CSNode *f=NULL;
if(t!=NULL)
{
if(t->data==x)
{
f=t;
}
else
{
f=Traverse(t->firstchild,x);//在左子树中找
if(f==NULL)
{
f=Traverse(t->nextsibling,x);
}
}
}
return f;//返回查找标志
}
int Create_CSTree(CSTree &t,int a,int b)
{
if(t==NULL)
{
///t = (CSNode*)malloc(sizeof(CSNode));
t=new CSNode;
t->data = a;
t->firstchild = new CSNode;
t->nextsibling=NULL;
t->firstchild->data = b;
t->firstchild->firstchild=NULL;
t->firstchild->nextsibling=NULL;
}
else
{
/// 查找 新输入的 a 是否在已存在的二叉链表中也有与a相等的
///节点 有的话 在其firstchild的节点上添加兄弟节点
CSNode *p;
p = Traverse(t,a); ///传值没问题
if(p==NULL)
{
return -1;
//printf("input wrong!\n");
}
if(p->firstchild != NULL)
{
CSNode *q;
q = p->firstchild;
for(int i = 0; ; i++)
{
if(q->nextsibling==NULL)
{
break;
}
else
{
q = q->nextsibling;
}
}
q->nextsibling = new CSNode;
q->nextsibling->data = b;
q->nextsibling->firstchild=NULL;
q