《剑指offer》– 树的子结构、二叉树的镜像、二叉树的深度、平衡二叉树

《剑指offer》– 树的子结构、二叉树的镜像、二叉树的深度、平衡二叉树

一、 树的子结构:

1、题目:

输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构。

2、解题思路:

这个题比较简单,利用递归的方式就可以判断B是不是A树的子结构。

3、实现代码:

    public boolean HasSubtree(TreeNode root1,TreeNode root2) {
		//当tree1和tree2都不为空的时候,才进行比较。否则直接返回false
		if(root1 ==null || root2 == null){
			return false;
		}
		
		以这个根节点为、根节点左子树、右子树 为起点判断是否包含Tree2
		return (isSubtree(root1,root2) || HasSubtree(root1.left,root2) || HasSubtree(root1.right, root2));
    }


	private boolean isSubtree(TreeNode root1, TreeNode root2) {
		//以下两个if的顺序不能调换
		//如果tree2已经遍历完了,表示都可以对应上,返回true
		if(root2==null)
			return true;
		//如果tree2已经遍历完,tree1还没遍历完,返回false
		if(root1==null)
			return false;
		
		//如果根节点对应的上,那么就分别去子节点里面匹配
		if(root1.val ==root2.val){
			return (isSubtree(root1.left,root2.left) && isSubtree(root1.right, root2.right));
		}else{
			return false;
		}
	}

 

 

二、二叉树的镜像:

1、题目:

操作给定的二叉树,将其变换为源二叉树的镜像。

2、输入描述:

二叉树的镜像定义:源二叉树 
    	    8
    	   /  \
    	  6   10
    	 / \  / \
    	5  7 9 11
    	镜像二叉树
    	    8
    	   /  \
    	  10   6
    	 / \  / \
    	11 9 7  5

3、解决思路:

采用递归的方式,递归交换每一个父节点的两个子节点的位置。

4、实现代码:

/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    public void Mirror(TreeNode root) {
        if(root==null)
            return ;
         if(root.left==null && root.right==null)
           return;
       
        TreeNode temp=root.left;
        root.left=root.right;
        root.right=temp;
        
        Mirror(root.left);
        Mirror(root.right);
    }
}

 

 

三、二叉树的深度:

1、题目:

输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

2、解决思路:

递归方式和层序遍历方式都可以解决。

3、代码实现:

public class Test3 {
	
	//第二种:非递归方式:层序遍历:
	public int TreeDepth(TreeNode root) {
		if(root == null){
			return 0;
		}
		
		Queue<TreeNode> queue = new LinkedList<TreeNode>();
		queue.add(root);
		//depth代表当前节点所在的层数,count代表已经遍历的节点数,nextCount代表下一层的节点数
		//当count==nextCount的时候,代表本次节点已经遍历完毕
		int depth=0,count=0,nextCount=1;
		
		while(queue.size()!=0){
			count++;
			TreeNode top = queue.poll();
			if(top.left!=null){
				queue.add(top.left);
			}
			if(top.right!=null){
				queue.add(top.right);
			}
			
			if(count==nextCount){
				depth++;
				count=0;
				nextCount=queue.size();
			}
		}
		return depth;
    }
	
	//第一种:递归方式
	public int TreeDepth1(TreeNode root) {
		if(root == null){
			return 0;
		}
		int left= TreeDepth1(root.left);
		int right =TreeDepth1(root.right);
		
		return Math.max(left, right)+1;
    }
}

class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}

 

 

四、平衡二叉树:

1、题目:

输入一棵二叉树,判断该二叉树是否是平衡二叉树。

2、解题思路:

递归方式或者后序遍历的方式都可以解决。

3、代码实现:

public class Test5 {
	
	private boolean isBalanced = true;
	//第三种:后续遍历时,遍历到一个节点,其左右子树已经遍历  依次自底向上判断,每个节点只需要遍历一次
	public boolean IsBalanced_Solution2(TreeNode root) {
		getDepth2(root);
		return isBalanced;
	}
	
	public int getDepth2(TreeNode root){
		if(root == null){
			return 0;
		}
		int left=getDepth2(root.left);
		int right=getDepth2(root.right);
		
		if(Math.abs(left-right)>1){
			isBalanced=false;
		}
		return Math.max(left, right)+1;
	}
	
	
	//第二种方法:三种中最好的方式
	//如果改为从下往上遍历,如果子树是平衡二叉树,则返回子树的高度;如果发现子树不是平衡二叉树,
	//则直接停止遍历,这样至多只对每个结点访问一次。
	public boolean IsBalanced_Solution1(TreeNode root) {
		return getDepth(root) !=-1;
	}
	
	public int getDepth(TreeNode root){
		if(root == null) return 0;
		int left=getDepth(root.left);
		if(left == -1 ) return -1;
		int right=getDepth(root.right);
		if(right == -1) return -1;
		
		return Math.abs(left-right)>1?-1:1+Math.max(left, right);
	}
	
	
	//第一种方法:递归方式
	//这种做法有很明显的问题,在判断上层结点的时候,会多次重复遍历下层结点,增加了不必要的开销。
	 public boolean IsBalanced_Solution(TreeNode root) {
		 if(root == null){
			 return true;
		 }
		 return Math.abs(maxDepth(root.left)-maxDepth(root.right))<=1
		 && IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
    }
	 
	 private int maxDepth(TreeNode root){
		 if(root == null){
			 return 0;
		 }
		 return 1+Math.max(maxDepth(root.left), maxDepth(root.right));
	 }
}


class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;
    public TreeNode(int val) {
        this.val = val;
    }
}

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/114698.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • python常见的数据类型有哪些?

    python常见的数据类型有哪些?变量用来存储数据,那么大家有没有想过,我们应该让变量占用多大空间,保存什么样的数据呢?在讲解变量的类型之前,我们先来看一个生活中的例子,例如,我们要运送一台电脑,大卡车和小轿车都可以完成,但是,如果使用大卡车运送一台电脑,显然有点小题大做,浪费了大卡车的空间,如图1所示。图一:卡车和轿车运输一台电脑同理,如果使用变量存储数据时,为了更充分利用内存空间,我们可以为变量指定不同的数据类型。Python中常见的数据类型如图2所示图二:Python变量数据类型图二中罗列了Python中常见的数据类型,下

    2022年6月4日
    26
  • docker 启动MYSQL[通俗易懂]

    docker 启动MYSQL[通俗易懂]https://blog.csdn.net/toupiOfRivia/article/details/78802668查看容器id的命令格式:dockerps-a删除一个容器dockerrmxxx查看所有镜像命令dockerimagels-a查看运行的镜像dockerps运行ngix[root…

    2022年9月28日
    0
  • 判断处理器是大端还是小端_网络字节序是大端还是小端

    判断处理器是大端还是小端_网络字节序是大端还是小端最近用杰理AC6966B调试博通的BK9527U段发射芯片,一直没调通,经过测试IIC通讯是通,硬件还是好的,但是怎么都调不到与接收端成功连接。最后咨询原厂得知提供的demo代码是大端编码模式的MCU代码,如果是小端模式,在部分写寄存器操作的过程中,如果直接传指针数据会反掉。杰理的MCU应该是小端模式,平时写代码用memcpy函数操作指针赋值最后得到的结果都是低位在前。为了进一步验证,网上找了一段代码验证,原理跟memcpy给指针赋值是类似的,最后成功验证到杰理的AC,AD系列都是小端模式:

    2022年8月30日
    3
  • 会员 数据库表设计[通俗易懂]

    会员 数据库表设计[通俗易懂]http://www.cnblogs.com/wuhuacong/p/3957428.html

    2022年6月20日
    50
  • Python负数取余总结

    Python负数取余总结Python负数取余总结余数存在正余数和负余数,要了解负余数,需要先了解取整原理17//5=3-17//5=-417//-5=-4-17//-5=3根据上述的4个公式,可以看出python的编译器是的取整符号位由被除数和除数同时决定,整数的数值是由向下取整的,即如果整数的符号位正,则取靠近0的数,如果整数是负数,则取远离0的数或者也可以这样理解:被除数和除数处于0的一边就往靠0的方向取整,如果是处于0的两边就往远离0的方向取整。了解了取整原理后,再理解取余就比较简单了17

    2022年5月8日
    37
  • mysql通配符_mysql通配符使用

    mysql通配符_mysql通配符使用mysql通配符使用:w3cchool在mysql查询中,经常会用到通配符,而且mysql的通配符和pgsql是有所不同的,甚至mysql中还可以使用正则表达式。本文就为大家带来mysql查询中通配符的使用。SQL模式匹配:“_”匹配单个字符,”\_”匹配”_”“%”匹配任意个字符,包括零个字符sql模式下的匹配,缺省是对于字母的大小写没有要求,并且sql模式下,“=”或”!=”是不能在模…

    2022年6月24日
    31

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号