二叉树的深度 判断二叉树是否平衡 38

?
?

问题一

?
?

引言

?
?

在之前我们讲到过如果保存树根节点到叶子节点之间的路径,其中包含了如何判断一个节点是否是叶子节点,而且用栈保存了路径中的节点,只要遍历一下栈即可,然后用一个深度保存所有遍历深度中的最大值

?
?

但仔细想想,这种方法是否过于繁琐,我们其实不需要一个完整的路径,为什么要去用一个栈保留路径呢,我们仅仅需要的是深度而已,所以我们可以从深度的角度出发去思考问题

?
?

分析问题

?
?

考虑递归,一棵树的深度一定是左子树和右子树深度较大值加1

?
?

左子树如果是空,那就是右子树的深度加1,其实这个情况也包含到了上面的情况中,这种情况中左子树的深度为0,肯定在比较大小中被淘汰了

?
?

解决问题

?
?

public int treePath(BinaryTreeNode root)

{

if(root==null)

return 0;

int left=treePath(root.lefNode);

int right=treePath(root.rightNode);

return left>right?(left+1):(right+1);

}

?
?

问题二

?
?

引言

?
?

有了问题一的基础,我们很想当然的会想到一个方法,是对于根节点,由之前的treePath得到左右子树的高度,如果左右子树高度差大于1,那么必然不是平衡的,如果高度差不大于1,那么递归遍历左右孩子是否满足根节点的特性

?
?

但是这样的方法稍加思考一下就会发现,根节点会去遍历最左下角的节点,根节点的左孩子也会去遍历最左下角的节点,这说明有很多节点被重复遍历了多次,这个跟求斐波拉契数中用到递归的方式很像,大家估计也能想象用这种递归算斐波拉契是多么的慢,所以这是很难忍受的

?
?

分析问题

?
?

如何规避这种重复遍历某些节点多次呢,我们想到用斐波拉契数求法中保留中间变量的思想,迭代进行,而在二叉树中如何迭代呢,最好的方式就是我们遍历到某一子树根节点的时候已经遍历完它的左右孩子,然后基于这个继续往上爬,也就是说我们从下往上看,而不是从上往下看

?
?

这个特性正是二叉树的后序遍历特性,左右根的顺序

?
?

解决问题

?
?

根据之前的分析,我们在判断一个二叉树是否平衡时,运用后序遍历的思想,先递归到左子树,在递归到右子树,最后回到根节点,每一层都是如此,只有当左右返回都为true时,才考虑根节点的情况

?
?

public boolean isBalanced(BinaryTreeNode root) {

if (root == null) {

return true;

}

boolean leftFlag = isBalanced(root.lefNode);

boolean rightFlag = isBalanced(root.rightNode);

if (leftFlag && rightFlag) {

return baseIsBalanced(root);

}

return false;

}

?
?

这里考虑根节点的时候用到了一个baseIsBalanced的基础方法,用于判断根节点是否满足平衡性,而这个基础方法中又用到之前我们说的计算树的深度的函数

?
?

public int treePath(BinaryTreeNode root) {

if (root == null)

return 0;

int left = treePath(root.lefNode);

int right = treePath(root.rightNode);

return left > right ? (left + 1) : (right + 1);

}

?
?

public boolean baseIsBalanced(BinaryTreeNode root) {

int left = treePath(root.lefNode);

int right = treePath(root.rightNode);

if (left - right >= -1 && left - right <= 1) {

return true;

} else {

return false;

}

}

?
?

?
?

时间: 2024-08-28 09:01:25

二叉树的深度 判断二叉树是否平衡 38的相关文章

《剑指offer》面试题39 二叉树的深度(java)

摘要: 今天翻到了<剑指offer>面试题39,题目二中的解法二是在函数的参数列表中通过指针的方式进行传值,而java是没有指针的,所以函数要进行改造.然而我翻了下别人的java版本(我就想看看有什么高大上的改造,毕竟要传递多个参数,是不是会涉及到那么一点点设计模式呢?),简直不能忍了,我只能用一句话形容:"一本正经的胡说八道",不过我就是喜欢看你胡说八道还迷之自信的样子. 下面吐槽一下这个版本的java代码: 1 //高效率的判断是否是一棵平衡二叉树 2 public b

判断二叉树是不是平衡二叉树

题目:输入一棵二叉树的根结点,判断该树是不是平衡二叉树.某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵二叉树. 我们很容易就能想到一个代码简洁却性能不佳的思路:在遍历树的每个结点的时候,调用函数TreeDpth得到它的左右子树的深度.如果每个结点的左右子树的深度相差都不超过1,按照定义它就是一棵平衡的二又树. 较好的思路是:用后序遍历的方式遍历整棵二叉树.在遍历某结点的左右子结点之后,我们可以根据它的左右子结点的深度判断它是不是平衡的,并得到当前结点的深度.当最后遍历到树的根结点

剑指Offer面试题39(Java版):二叉树的深度

题目:输入一棵二叉树的根节点,求该数的深度.从根节点到叶结点依次进过的结点(含根,叶结点)形成树的一条路径,最长路径的长度为树的深度. 例如,如下图的二叉树的深度为4,因为它从根节点到叶结点的最长的路径包含4个结点(从根结点1开始,经过2和结点5,最终到达叶结点7) 我们可以从另一种角度来理解树的深度.如果一棵树只有一个结点,它的深度为1,如果根节点只有左子树而没有右子树,那么树的深度应该是其左子树的深度+1.同样如果根节点只有右子树而没有左子树,那么树的深度应该是其右子树+1.如果既有左子树又

判断二叉树是否平衡

题目:输入一棵二叉树的根结点,判断该树是不是平衡二叉树.如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树. 注:这里不考虑该二叉树是否是二叉排序树 解决要点: 1.后序遍历二叉树: 2.递归. 核心算法: bool isBalanced(pTree pT,int *depth) { if(!pT)//参数判断 { *depth = 0; return true; } //后序遍历 int left,right; if(isBalanced(pT->lChild,&

判断任一二叉树,是否为满二叉树.(输出二叉树,节点总数,二叉树深度)

#include "stdio.h"#include "malloc.h"int count;typedef struct node{ char data; struct node *LChild; struct node *RChild;}BiTNode,*BiTree; void creatbitree(BiTree * bt) // 先序便历序列创建二叉树链表{ char ch=getchar(); if (ch=='#') {  *bt=NULL; } el

求一个二叉树的深度以及如何判断一个二叉树是一个平衡二叉树

/** * Created by Administrator on 2015/10/10. */public class TreeNode { //树节点的值 private char data; //节点的左子树 private TreeNode leftTree; //节点的右子树 private TreeNode rightTree; public TreeNode(char data,TreeNode leftTree,TreeNode rightTree){ this.data=dat

56. 2种方法判断二叉树是不是平衡二叉树[is balanced tree]

[本文链接] http://www.cnblogs.com/hellogiser/p/is-balanced-tree.html [题目] 输入一棵二叉树的根结点,判断该树是不是平衡二叉树.如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树.例如下图中的二叉树就是一棵平衡二叉树: [分析] 之前的博文27.二元树的深度[BinaryTreeDepth]中介绍过如何求二叉树的深度.有了经验之后再解决这个问题,我们很容易就能想到思路. [方案1] 先判断左右子树是不是平衡的

二叉树的深度(平衡二叉树)

题目 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 思路 如果一棵树只有一个结点,它的深度为1,如果根节点只有左子树而没有右子树,那么树的深度应该是其左子树的深度+1.同样如果根节点只有右子树而没有左子树,那么树的深度应该是其右子树+1.如果既有左子树又有右子树,那概述的深度就是左.右子树的深度的较大值加1. #include <iostream> using namespace std; struct tree {

二叉树各种相关操作(建立二叉树、前序、中序、后序、求二叉树的深度、查找二叉树节点,层次遍历二叉树等)(C语言版)

将二叉树相关的操作集中在一个实例里,有助于理解有关二叉树的相关操作: 1.定义树的结构体: 1 typedef struct TreeNode{ 2 int data; 3 struct TreeNode *left; 4 struct TreeNode *right; 5 }TreeNode; 2.创建根节点: 1 TreeNode *creatRoot(){ 2 TreeNode * root =(TreeNode *)malloc(sizeof(TreeNode)); 3 if(NULL=