求二叉树的高度,可以用递归的思想去求解,也可以用非递归的思想去求解,只不过,递归的代码简单明了,但是总的来说,递归有递归的好处,非递归当然也有非递归的好处。
求树的高度的递归思想和递归建树的思想差不多:
从最底层的子树(结点)开始,求每颗子树(个结点)的左子树和右子树的高度,返回最大的那颗子树的高度,即每递归一次便加1
具体核心代码如下:
int getHight(BiNode<T>*t) //递归寻找高度
{
int deep=0;
if(t!=NULL)
{
int lchild_hight=getHight(t->lchild); //树的左子树的高度
int rchild_hight=getHight(t->rchild); //树的右子树的高度
deep=(lchild>=rchild)?(lchild_hight+1):(rchild_hight+1); //deep取最大值
}
return deep; //返回deep
}
如果递归思想不太明白的,建议去看看盗梦空间哟!
关于非递归的思想,通过遍历整棵二叉树,找出叶子结点,然后在从叶子结点回溯到树的根结点,通过结算结点个数,加1便是树高了
具体代码如下:
void TreeHight(BiNode<T>* &t) //中序遍历改造为寻找树高
{
using std::stack;
t->father=NULL;
stack<BiNode<T>*>leafstack;//存储叶子结点的栈
stack<BiNode<T>*>nodeStack;//存储待访问的结点
BiNode<T>*pointer=t;
while(!nodeStack.empty()||pointer) //栈为空时结束遍历
{
if(pointer){
nodeStack.push(pointer); //当前结点入栈
pointer=pointer->lchild; //转向访问左子树
}
else{
pointer=nodeStack.top(); //读取栈顶元素
if(pointer->lchild==NULL&&pointer->rchild==NULL) //判断是否为叶子结点
leafstack.push(pointer); //若为叶子结点,存储到相应的栈中
pointer=pointer->rchild; //转向访问右子树
nodeStack.pop(); //栈顶元素退栈
}
}
//叶子结点的地址在leafstack栈中呈线性排列
int Hight=0;//第n个叶子结点的高度
int hight=0;//第n+1个叶子结点的高度
while(!leafstack.empty())
{
hight=0; //初始化为0
pointer=leafstack.top(); //读取栈顶的叶子结点
while(pointer->father!=NULL) //当叶子栈为空时结束
{
hight++;
pointer=pointer->father;//回溯到其双亲结点
}
leafstack.pop(); //栈顶元素退栈
if(Hight<hight) //当前叶子结点的高度若比之前一个的叶子高度大,则赋值给前一个高度
Hight=hight;
}
cout<<"树高为:"<<hight+1<<endl;
}
当然,如果是用非递归思想,那我们在遍历的时候就该用层次遍历咯
不过过程中有一个father指针的标记倒是用到了递归的思想
完全代码如下:
#include<string>
#include<iostream>
#include<stack>
using namespace std;
//二叉链表表示二叉树
template<class T>
class BiNode
{
public:
T data;//节点数据
BiNode * lchild;//左孩子
BiNode * rchild;//右孩子
BiNode *father;//双亲
BiNode();
BiNode(T d){ data=d; } //new一个结点的时候就给其数据域赋值
~BiNode(){}
void createTree(BiNode<T>* &t, string pre,string in) //后序,中序
{
if(pre.length()==0)
{
t=NULL;
}
if(pre.length()!=0)
{
t=new BiNode<T>(pre[0]);
int index=in.find(pre[0]);
string in_left_str=in.substr(0, index);
string in_right_str=in.substr(index+1);
string pre_left_str=pre.substr(1, index);
string pre_right_str=pre.substr(index+1);
if(t!=NULL)
{
createTree(t->lchild,pre_left_str,in_left_str);
createTree(t->rchild,pre_right_str,in_right_str);
}
}
}
void preOrder(BiNode<T> *t)
{
if(t==NULL)
{
return ;
}
if(t!=NULL)
{
cout<<t->data;
preOrder(t->lchild);
preOrder(t->rchild);
}
}
void inOrder(BiNode<T> *t)
{
if(t==NULL)
{
return ;
}
if(t!=NULL)
{
inOrder(t->lchild);
cout<<t->data;
inOrder(t->rchild);
}
}
void TreeHight(BiNode<T>* &t) //中序遍历改造为寻找树高
{
using std::stack;
t->father=NULL;
stack<BiNode<T>*>leafstack;//存储叶子结点的栈
stack<BiNode<T>*>nodeStack;//存储待访问的结点
BiNode<T>*pointer=t;
while(!nodeStack.empty()||pointer) //栈为空时结束遍历
{
if(pointer){
nodeStack.push(pointer); //当前结点入栈
pointer=pointer->lchild; //转向访问左子树
}
else{
pointer=nodeStack.top(); //读取栈顶元素
if(pointer->lchild==NULL&&pointer->rchild==NULL) //判断是否为叶子结点
leafstack.push(pointer); //若为叶子结点,存储到相应的栈中
pointer=pointer->rchild; //转向访问右子树
nodeStack.pop(); //栈顶元素退栈
}
}
//叶子结点的地址在leafstack栈中呈线性排列
int Hight=0;//第n个叶子结点的高度
int hight=0;//第n+1个叶子结点的高度
while(!leafstack.empty())
{
hight=0; //初始化为0
pointer=leafstack.top(); //读取栈顶的叶子结点
while(pointer->father!=NULL) //当叶子栈为空时结束
{
hight++;
pointer=pointer->father;//回溯到其双亲结点
}
leafstack.pop(); //栈顶元素退栈
if(Hight<hight) //当前叶子结点的高度若比之前一个的叶子高度大,则赋值给前一个高度
Hight=hight;
}
cout<<"树高为:"<<hight+1<<endl;
}
int getHight(BiNode<T>*t) //递归寻找高度
{
int deep=0;
if(t!=NULL)
{
int lchild_hight=getHight(t->lchild); //树的左子树的高度
int rchild_hight=getHight(t->rchild); //树的右子树的高度
deep=(lchild>=rchild)?(lchild_hight+1):(rchild_hight+1); //deep取最大值
}
return deep; //返回deep
}
void DeFineFather(BiNode *t)//递归标记结点的双亲
{
if(t!=NULL)
{
if(t->lchild!=NULL)
t->lchild->father=t;
if(t->rchild!=NULL)
t->rchild->father=t;
DeFineFather(t->lchild);
DeFineFather(t->rchild);
}
}
};
int main()
{
BiNode<char>*t=NULL;
string pre="ABDFGCEH";
string in="BFDGACEH";
t->createTree(t,pre,in);
/*
cout<<"前序遍历"<<endl;
t->preOrder(t);
cout<<endl;
cout<<"中序遍历"<<endl;
t->inOrder(t);
cout<<endl;*/
t->DeFineFather(t);
t->TreeHight(t);
cout<<endl;
cout<<"递归寻求树的高度:"<<t->getHight(t)<<endl;
return 0;
}