求二叉树高度的递归算法中递归过程理解

int GetHeight(AVLTree A)
{
    int MaxH, HR, HL;
    if(A) {
        HL = GetHeight(A->Left);
        HR = GetHeight(A->Right);
        MaxH = (HL>HR)?HL:HR;
        return MaxH+1;
    }
    return 0;
}

1.递归函数关注以下几个因素
·退出条件
·参数有哪些
·返回值是什么
·局部变量有哪些
·全局变量有哪些
·何时输出
·会不会导致堆栈溢出

2.

求二叉树高度的递归算法中递归过程理解_第1张图片

 

3.理解递归的时候不能一直往深处考虑,那样不适合人类的思维,只需要思考最后该退出时要返回什么,一般的情况下该返回什么,写代码时明确了这两个即可

4.

int Hight(Node* root)
    {
        if ( !root )
            return 0;
        else
            return max(Hight(root->left_child),Hight (root->right_child)) + 1
    }

!root , 也就是指针为空的时候返回 0;
就是说,遇到空节点,返回 0 ;

下一行: return max()+ 1 ;
这个是关键点,返回每一个子节点的高度,
括号内,是调用自身这个函数(返回节点树高度)

整个函数的思想可以看做是分治:即把大问题分解成小问题,对于整体函数,不需要知道每一步的执行过程,只需要知道上一步的结果就可以。

每个函数调用自身,判断出是否需要继续调用函数,还是直接返回最根部的值 0 。如果调用函数,即需要获取调用函数的返回值即可。

如果想理解这个函数,提供一个逆向的思维方式,从叶子结点开始思考,也就是  !root 那一行,返回了 0 ,调用他的函数 作对比,取最高值(深度最深值),依次递增到根节点或所输最外层节点,最终返回最大深度。

实现性原理:
每次递归调用一次函数时,计算机都会新开辟出一段函数空间、存储空间,为当前新调用的函数提供存在的空间。  以这个函数的运行为例,系统最终会开辟一个类似树形连接的区域,然后再依次确定每个函数的返回值(从叶子结点开始)。

所以,递归,也是一种 典型的 用空间换时间 的算法。

 

5.如果root是空就返回0,如果非空就遍历子树。取最高子树,然后加1就得到了整棵树的高度。就这样递归下去的

6.


左子树的高度height(llink) 
右子树的高度height(rlink) 
这两个高度当然要取更大的数 对吧 
加上自己的节点 1: 
      本次递归的p------> O(p) 
                      /  \ 
                     /    \ 
height(llink)------>左子树  右子树 <----------height(rlink) 
总的高度 为 1 + max(height(llink),height(rlink)); 

7.


public int height(BinaryTreeNode p) {  //p是一个二叉树根节点的引用
    if(p == null){
       System.out.println("高度为0")
       return 0;
     }else{
       return 1 + max(height(llink),height(rlink));  //这个LLINK 和RLINK分别是p的两个指针,指向左子树和右子树
     }
}

你可以这样理解:
首先你就当height可以求出某个节点的高度
从根节点开始,怎么表示这棵树的高度?根节点一层,左右子树,谁层数多,当然加上谁的啦
所以 return 1 + max(height(llink),height(rlink));
然后对llink或者rlink都是同样的理解
最后什么时候返回?当然是节点为空的时候啦,因为一个叶子节点已经是最后一层,它的左右节点
都是空的。

你可能感兴趣的:(数据结构与算法)