二叉树:求树的高度(递归和非递归算法)

题目:假设二叉树采用二叉链表存储结构,设计一个算法求二叉树的高度。

递归

分析:用递归方式来实现比较抽象,有一种没有解决问题的错觉。如果要理解递归,就要理解递归。。。但是递归的代码量少,简洁。如图,要以一种抽象化的方式来理解。不能具体,一旦具体了,就跟啥都没解决似的。
二叉树:求树的高度(递归和非递归算法)_第1张图片

算法思想:递归左子树高度和右子树的高度,取较大者+1。
代码

int BTdepth(BiTree T){  // 求树的高度depth
	if(T!=NULL)  // 空树的高度为零
		return 0;
	ldepth=BTdepth(T->lchild);  // 求左孩子的高度
	rdepth=BTdepth(T->rchild);  // 求右孩子的高度
	if(ldepth>rdepth) 
		ldepth=ldepth+1;  
		// 树的高度为最大高度的子树加个根结点
		return ldepth;
	else
		rdepth=rdepth+1;
		return rdepth;
}

非递归

分析:非递归比较难理解,是在层次遍历的基础上进行改造,也是借助队列完成。那么如何要求出树的高度?可以让一个变量last始终指向每一层最右端的结点,指了几个结点,就有几层,即二叉树的高度。
如图,rear指向入队的结点,front指向要出队的结点,last指向当前层最右端的结点。last是一个普通的变量,值为0,rear和front是队列的,指向-1。二叉树:求树的高度(递归和非递归算法)_第2张图片
根结点A入队,rear指向A
二叉树:求树的高度(递归和非递归算法)_第3张图片
然后front前进一步,front指向A,A出队,访问,A有BC两个左右孩子,BC入队,front等于last,所以将last指向rear。注意只要front等于last了,就将last指向rear。二叉树:求树的高度(递归和非递归算法)_第4张图片
二叉树:求树的高度(递归和非递归算法)_第5张图片

然后front前进一步,front指向B,B出队,访问,B有DE两个左右孩子,DE入队。
front前进一步,指向C,C没有左右孩子,C直接出队。
rear指向最后入队结点E。
此时front等于last,所以将last指向rear。二叉树:求树的高度(递归和非递归算法)_第6张图片
front往前走一步,指向D,D没有左右孩子,直接出队。
二叉树:求树的高度(递归和非递归算法)_第7张图片
front向前走一步,指向E,E出队,访问,发现E有FG两个左右孩子,将FG入队,rear指向G,此时front=last,所以将last指向rear指向的结点。
二叉树:求树的高度(递归和非递归算法)_第8张图片
front前进一步,指向F,没有左右孩子,直接出队;
front再前进一步,指向G,没有左右孩子,直接出队;
此时front=rear,结束循环,最终rear分别指向过ACEG,恰好是每层最右端的结点,结点个数为4,所以此二叉树的高度为4。
二叉树:求树的高度(递归和非递归算法)_第9张图片
总结:rear指向每次入队的最后结点,front每次向前走一步,当fronreat时lastrear。这就是核❤思想。然后层数level加1,最后level的值就是二叉树的高度。

算法思想:采用层次遍历的算法,设置变量level记录当前结点所在的层数,设置变量last指向当前层的最右结点,每次层次遍历出队时与last指针比较,若两者相等,则层数加1,并让last指向下一层最右端的结点,直到遍历完成。level的值即为二叉树的高度。核❤问题在于如何让last指向每层最右端的结点。

代码

int BTdepth(BiTree T){
	if(T==NULL)  // 空树的高度为0
		return 0;
	int front=-1,rear=-1;  // 初始化一个空的队列
	int last=0,level=0;  
	// last指向当前层的最右结点,level记录树的层数
	BiTree Q[MaxSize];  // 假设队列足够大
	Q[++rear]=T;  // 根结点入队
	BiTree p;  // 初始化指针p
	while(front<rear){  
	// 队列不空,则循环
	// fornt
		p=Q[++front];  
		// front指向要出队的结点
		// 当前front指向的队列元素出队并访问
		if(p->lchild)  // 如果有左孩子
			Q[++rear]=p->lchild;  // 左孩子入队
		if(p->rchild)  // 如果有右孩子
			Q[++rear]=p->rchild;  // 右孩子入队
		if(front==rear){  // ❤
			level++;  // 层数加1
			last=rear;  // ❤
		}
	}
	return level;
}

你可能感兴趣的:(数据结构,数据结构,图论,b树,算法)