PTA 求二叉树高度(递归与非递归实现)

题目要求 :

本题要求给定二叉树的高度。

函数接口定义:

int GetHeight( BinTree BT );

要求函数返回给定二叉树BT的高度值。

裁判测试程序样例:

#include <stdio.h>
#include <stdlib.h>

typedef char ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};

BinTree CreatBinTree(); /* 实现细节忽略 */
int GetHeight( BinTree BT );

int main()
{
    BinTree BT = CreatBinTree();
    printf("%d\n", GetHeight(BT));
    return 0;
}
/* 你的代码将被嵌在这里 */

实现代码:

递归:

int GetHeight(BinTree t){
    if(t==NULL) return 0;//当节点为空时返回0
    int l=GetHeight(t->Left);//递归计算所有左子树的高度
    int r=GetHeight(t->Right);//递归计算所有右子树的高度
    return (l>r?l:r)+1;//返回左树或右树的最大高度
}
函数具体实现过程:

以题目给出的二叉树为例:

每次递归时返回左右子树高度的最大值+1。

非递归:

typedef struct stack{
    BinTree ptr[100];//定义存储节点指针的栈
    int top;
}Stack;

Stack* create(){
    //初始化栈
    Stack* s=(Stack*)malloc(sizeof(Stack));
    s->top=-1;
    return s;
}

//压栈
void push(Stack* s,BinTree ptr){
    s->ptr[++s->top]=ptr;
}

//出栈
void pop(Stack* s){
    s->top--;
}

//辅助函数 判断栈空
int isEmpty(Stack* s){
    return s->top==-1;
}

int GetHeight(BinTree t){
    //遍历,直至栈和节点为空
    int height=0;
    int current_height=0;
    //初始化局部高度和总高度
    BinTree current=t;//当前节点
    BinTree last=NULL;//上一个处理的节点,初始化为NULL
    Stack* s=create();//创建栈
    while(current||!isEmpty(s)){
        while(current){
            push(s,current);//当前节点不为NULL,压入栈顶
            current=current->Left;//更新当前节点为左孩子
            current_height++;//当前高度自增
        }
        current=s->ptr[s->top];//当节点的左孩子为空
        //将当前节点设置为栈顶节点,但不弹出,暂时保存栈顶节点
        if(current->Right&&last!=current->Right){
            //当前节点的右孩子存在,且未被处理
            current=current->Right;//更新节点为右孩子
        }
        else{
            if(current_height>height) height=current_height;
            //更新总高度
            pop(s);//栈顶节点出栈
            last=current;//更新上一个处理的节点
            current_height--;//回溯高度
            current=NULL;//强制退出内层循环,处理下一个节点
        }
    }
    free(s);//释放栈的内存
    return height;//返回总高度
}
实现过程:

 假设有如下二叉树:

        A
       / \
      B   C
     / \   \
    D   E   F

遍历过程

步骤当前节点栈状态(从底到顶)current_heightheight操作
1A[A]10左转B
2B[A, B]20左转D
3D[A, B, D]30D无左/右
4D[A, B, D]33回溯到B
5B[A, B]23右转E
6E[A, B, E]33E无左/右
7E[A, B, E]33回溯到B
8B[A, B]23回溯到A
9A[A]13右转C
10C[A, C]23C无左,右转F
11F[A, C, F]33F无左/右
12F[A, C, F]33回溯到C
13C[A, C]23回溯到A
14A[A]13栈空,结束

最终返回 height = 3(最长路径 A→B→D 或 A→C→F)。

 总结:

1、递归实现只适合处理规模不大的树。

2、非递归实现则可以处理大规模数据,但是在这一段代码中定义了一个last的变量来存储上一个处理的节点,使得逻辑变得更复杂。

可以在栈中增加一个数组来存储各节点的高度并随弹栈更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值