1.方法思路:用深搜和后序遍历结合,遍历所有节点,记录最大高度。时间为O(n),空间为O(max)。(自创)
代码如下(未测试):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | int DFS_PostOrder(BiTree T){
if (!T) return 0; //树空,高度为0
InitStack(S);
BiTree *p=T,*r=NULL; //r为后序遍历时的辅助指针
int num=0,max=0; //num用来跟随程序实时记录层数,max用来记录最大值
while (p||!isEmpty(S)){ //以下为后序遍历略作修改
while (p){ //该结点入栈并搜索其左孩子
Push(S,p);
num++;
if (num>max) max=num;
p=p->lchild;
}
Get(S,p);
if (p->rchild&&p->rchild!=r) p=p->rchild; //如果右孩子存在并还没访问,则访问
else {
Pop(S,p);
num--; //出栈则层数减1
r=p; //r指向上一个访问节点
p=null;
}
}
ruturn max; //返回最大高度
}
|
2.方法思路:用层序遍历,这里需要记录每一层的第一个结点r,用于计算层数。时间为O(n),空间为结点最多的层*2。(自创)
代码如下(未测试):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | int TreeHeight(BiTree T){
if (!T) return 0; //树空,高度为0
InitQuece(Q);
int max=0; //记录树高度
BiTree *p=T,*r=null; //r记录每一层的第一个结点
EnQuece(Q,p);
while (!isEmpty(Q)){ //寻找下一层的第一个结点
int pd=0; //判定是否找到下一层的第一个结点
while (pd=0&&!isEmpty(Q)){
DeQuece(Q,p);
if (p->lchild!=Null){
EnQuece(Q,p->lchild);
r=p->lchild;
pd=1; //已找到
}
if (p->rchild!=Null){
EnQuece(Q,p->rchild);
if (pd=0){
r=p->lchild;
pd=1; //已找到
}
}
}
if (!isEmpty(Q)) Get(Q,p);
while (r!=p&&!isEmpty(Q)){ //处理该层剩余结点的孩子结点,使其入队
DeQuece(Q,p);
if (p->lchild!=Null){ EnQuece(Q,p->lchild);}
if (p->rchild!=Null){ EnQuece(Q,p->rchild);}
}
max++; //该层结点遍历完毕,层数+1
}
return max;
}
|
3.方法思路:层次遍历+队列应用,设置变量level记录当前结点所在层数,设置变量last指向当前层最后结点,每次层次遍历出队时与last指针比较,若两者相等,那么层数加1,并让last指向下一层最右结点,至遍历完成。level的值即为二叉树的高度。时间为O(n),空间为O(n)。(王道书所述)
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | int Btdepth(BiTree T){
//采用层次遍历的非递归方法求解二叉树的高度
if (!T) return 0; //树空,高度为0
int front=-1,rear=-1;
int last=0,level=0; //last指向下一层第一个结点的位置
BiTree Q[MaxSize]; //设置队列Q,元素是二叉树结点指针且容量足够
Q[++rear]=T; //根结点入队
BiTree p;
while (front<rear){ //队不空,则循环
p=Q[++front]; //队列元素出队,则正在访问的结点
if (p->lchild) Q[++rear]=p->lchild; //左孩子入队
if (p->rchild) Q[++rear]=p->rchild; //右孩子入队
if (front==last){ //处理该层的最右结点
level++; //层数加1
last=rear; //last指向下层
}
}
return level;
}
|
4.递归方法
代码如下:
1 2 3 4 5 6 7 | int Btdepth(BiTree T){
if (T==NULL) return 0;
ldep=Btdepth(T->lchild); //左子树高度
rdep=Btdepth(T->rchild); //右子树高度
if (ldep>rdep) return ldep+1; //树的高度为子树最大高度加根结点
else return rdep+1;
}
|