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.
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都是同样的理解
最后什么时候返回?当然是节点为空的时候啦,因为一个叶子节点已经是最后一层,它的左右节点
都是空的。