二叉树最大高度和最小深度

目录

高度与深度的区别

 计算最大高度

递归

迭代

计算最小深度

递归

 迭代

总结:


 

高度与深度的区别

       高度由叶子节点开始计算,直到根节点,叶子节点的计数为0,所以最大高度就是根节点到最远叶子节点的距离减一

        深度由根节点处开始计算,直到叶子节点,根节点的计数为0.

 计算最大高度

递归

想要计算二叉树的最大高度,我们不如将其拆分成一个子问题,对于某一个根节点来说,最大高度就是其左右子树中较高的那一个。

int height(struct treenode* root)
{
	//终止条件
	if (NULL == root)
		return 0;
	//单层逻辑
	//归
	int left = height(root->left)+1;
	int right = height(root->right)+1;
	
	return max(left, right);

}

在这里我们对其中一个节点进行思考,并计算它的左右子树的高度,当到最底层时返回0,每次向上归的过程中数量+1,对于这个根节点而言,其高度为左右子树中较高的那一棵+1.

迭代

在这里使用层序遍历二叉树,如果使用前序遍历的话,每一次都需要记录下一条边的高度,并进行比较,无论是层序遍历还是前序遍历,计算最大高度都需要遍历完整个二叉树,在这里不如使用层序遍历省去比较的步骤。

int maxdepth(treenode* root)
	{
		int number = 0;
		//检查合法性
		if (NULL == root)
			return NULL;
		//创建队列
		queue<treenode*> que;
		que.push(root);
		while (!que.empty())
		{
			number++;
			int size = que.size();
			for (int i=0; i < size; i++)
			{
				//记录即将要弹出的节点
				struct treenode* temp = que.front();
				//弹出
				que.pop();
				//入孩子队列
				if(temp->left)
				que.push(temp->left);
				if(temp->right)
				que, push(temp->right);
			}
			
		}
		return number+1;
	}

其中,size计算每一层的所有元素,此外size只能在for循环外定义,因为队列的大小是在实时变化的。

for循环遍历每一层的所有成员,遍历完后由size记录队列大小,来进行下一层的遍历。

每次遍历完一层,计数器都+1.

计算最小深度

递归

         在计算二叉树最大高度时,我们利用递归,通过比较左子树和右子树的高度,并返回其中的较大值。

        那在计算二叉树最小深度时,我们是否也可以使用这种方法,比较并返回其中的较小值呢?

        让我们来思考其中的一种特殊情况:

当存在一个节点,他的左孩子为空,右孩子不为空,那么通过比较并返回其中较小值得方法就会直接返回那个空得节点,右孩子得那一条路就根本不会计算了。

但这个空节点根本不是最小深度,无论是最大深度还是最小深度,都指的是叶子节点,即左孩子和右孩子都为空。

 所以我们需要多考虑一个孩子为空的情况,即遇到这种节点时,不用管他,而是计算他下面的节点,即继续向下递即可。

int getmindepht(treenode* root)
	{
		//确定终止条件//同时也是确定的底
		if (NULL == root)
			return 0;
		//确定单层递归条件
		//一孩为空情况
		if (root->left == NULL && root->right != NULL)return 1 + getmindepht(root->right);
		if (root->left != NULL && root->right == NULL)return 1 + getmindepht(root->left);
		//接下来就是普通情况了
		return 1 + min(getmindepht(root->left), getmindepht(root->right));//后序遍历,涉及到左子树与右子树的比较
	}

 迭代

利用层序遍历,每一层计数,不过这次当遇到左孩右孩都为空时返回即可。即最小深度的叶子节点。

int mindepth(treenode* root)
	{
		int counter = 0;
		//检查合法性
		if (NULL == root)
			return NULL;
		//创建队列
		queue<treenode*> que;
		que.push(root);
		while (!que.empty())
		{
			counter++;
			int size = que.size();
			for (int i = 0; i < size; i++)
			{
				struct treenode* temp = que.front();
				que.pop();
				if(temp->left)
				que.push(temp->left);
				if(temp->right)
				que, push(temp->right);
				if (temp->left == NULL && temp->right == NULL)
					return counter;
			}

		}

	}

总结:

在计算最小深度时,往往容易陷入误区,而我们只需要将一个孩子为空的情况拎出以进行继续向下递即可。

  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值