问题描述:
现在有一棵合法的二叉树,树的节点都是用数字表示,现在给定这棵树上所有的父子关系,求这棵树的高度
输入描述:
输入的第一行表示节点的个数n(1 ≤ n ≤ 1000,节点的编号为0到n-1)组成,
下面是n-1行,每行有两个整数,第一个数表示父节点的编号,第二个数表示子节点的编号
输出描述:
输出树的高度,为一个整数
示例1
输入
5
0 1
0 2
1 3
1 4
输出
3
解题思路:
思路一:根据题目要求,依据父子关系建立一颗合法的二叉树,然后再利用递归得出树的高度。
但是再测试用例时有的用例会使用多叉树,这个算法不适用。而且多叉树在进行运算时,只能取前面两个分支,要忽略后面的分支。
源代码:
/*建立二叉树求解问题*/
#include<iostream>
using namespace std;
typedef struct Node
{
struct Node *lchild;
struct Node *rchild;
int val;
}BiTree,*LinkTree;
int flag; //判断函数递归是否结束
//求树的高度
int getTreeHeight(LinkTree rootNode)
{
if(rootNode==NULL) return 0;
int nLeft = getTreeHeight(rootNode->lchild);
int nRight = getTreeHeight(rootNode->rchild);
return (nLeft>nRight)?(nLeft+1):(nRight+1);
}
//依据节点建树
void CreatTree(LinkTree root,int father,int childVal)
{
// cout<<"CreatTree"<<endl;
//root->lchild=NULL;
//cout<<childVal<<" "<<father<<endl;
if(root==NULL) return;
// cout<<"Compare:"<<root->val<<" "<<father<<endl;
if(root!=NULL&&root->val==father)
{
// cout<<"INIT"<<endl;
if(root->lchild==NULL) //如果左子树为空,则建立左子树
{
root->lchild=new(BiTree);
root->lchild->val=childVal;
root->lchild->lchild=NULL;
root->lchild->rchild=NULL; //左右节点赋空
flag=1;
}
else //否则则建立右子树,因为合法,故非左即右
{
// cout<<"rchild"<<endl;
root->rchild=new(BiTree);
root->rchild->val=childVal;
root->rchild->lchild=NULL;
root->rchild->rchild=NULL;
flag=1;
}
return;
}
if(flag==0) //设置标记,防止无限调用循环,而且会减少函数调用的次数
{
CreatTree(root->lchild,father,childVal); //类似于深度优先,若一层不行,则往深入遍历
CreatTree(root->rchild,father,childVal);
}
else return;
}
int main()
{
int n,height;
cin>>n;
LinkTree root=new(BiTree);
root->val=0;
root->lchild=NULL;
//Creat(root,root->val,)
for(int i=0;i<n-1;i++)
{
flag=0;
int father;
int childVal;
cin>>father>>childVal;
CreatTree(root,father,childVal);
}
//cout<<root->val<<endl;
//cout<<root->rchild->val<<endl;
//cout<<root->rchild->val<<endl;
height=getTreeHeight(root);
cout<<height;
return 0;
}
思路二:通过递归关系的到深度,即子节点的深度等于父节点的深度加一。而从根节点开始,依次通过节点关系,来得出每一层的节点的深度。
核心代码:
/*父节点的深度加一就是子节点的深度,从0开始一次往下遍历*/
/*0的深度为1,一次以此为基础向下遍历,则可得到最终深度 */
#include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
int main()
{
int n;
int temp;
int BiHeight=0; //the result
int result[10000]={1};
vector<vector<int> > count; //to creat a array
cin>>n;
for(int i=0;i<n-1;i++)
{
vector<int> MiddleUse;
cin>>temp;
MiddleUse.push_back(temp);
cin>>temp;
MiddleUse.push_back(temp);
count.push_back(MiddleUse); //input the array
}
sort(count.begin(),count.end()); //sort to calculate
//for(int i=0;i<n;i++)
//cout<<count[i][0]<<" "<<count[i][1]<<endl;
for(int i=0;i<n-1;i++)
{
// cout<<count[i][1]<<endl;
result[count[i][1]]=result[count[i][0]]+1; //int the base of the count[0][0]
BiHeight=max(BiHeight,result[count[i][1]]); //to work out the depth
}
//cout<<count[0][0]<<result[1]<<result[2]<<result[3];
cout<<BiHeight<<endl;
}
此为两种两种计算深度的方式,其中第一种思路适用于所有已经建立的树,第二种适合与这种节点的关系来求深度。