March.29.2022——二叉树的相关概念及实现判断(一)

March.29.2022——二叉树的相关概念及实现判断(一)

1.如何判断一棵树是搜索二叉树:

  • 对于每一颗子树左边的树都比他自己小 右边比自己大
判断搜索二叉树方法:

中序遍历 后该二叉树不会降序;

解法一:代码实现
  1. 左树为搜索二叉树,左树上的最小值必须要大于我 返回值:是否为搜索二叉树,和最大值,最小值
  2. 右树为搜索二叉树,右树上的最大时要小于我 返回值:是否为搜索二叉树,和最小值,最大值
  3. //默认左树给我一个信息,得到三个返回值
  4. //默认右树给我一个信息,得到三个返回值
  5. //得到自己的三个返回值信息 整个递归才能链接起来
	public static class ReturData(){
		//默认左树给我一个信息,得到三个返回值
		//默认右树给我一个信息,得到三个返回值
		//得到自己的三个返回值信息 整个递归才能链接起来
		public boolean isBST;
		public int min;
		public int max;
		//构造函数
		public ReturData(boolean is,int mi,int ma){
			isBST = is;
			min = mi;
			max = ma;
		}
	}
	public static ReturData process(Node x){
		if(x == null){
			return ;
		}

		//默认左树给我一个信息,得到三个返回值
		//默认右树给我一个信息,得到三个返回值
		ReturData leftdata = process(x.left);
		ReturData rightdata = process(x.right);

		int min = x.value;
		int max = x.value;
		//如果左边的节点不为空  得到与左节点比较厚的最小值
		if(leftdata != null){
			min = Math.min(min,leftdata.min);
			max = Math.max(max,leftdata.max);
		}
		//如果右边的节点不为空 得到与右节点比较厚的最小值
		if(rightdata != null){
			min = Math.min(min,rightdata.min);
			max = Math.max(max,rightdata.max);
		}

		boolean isBST = true;//这句话是什么意思呢?
		if (leftdata != null &&(!leftdata.isBST || leftdata.max >= x.value)){
			return false;
		}
		if (rightdata != null &&(!rightdata.isBST || rightdata.min <= x.value)){
			return false;
		}
        
        //从boolean开始 有第二种解法:
        boolean isBST = false;
		if(
				(leftdata != null?(leftdata.isBST  &&  leftdata.max < x.value) : true)
				&&
						(rightdata != null?(rightdata.isBST  &&  rightdata.min > x.value) : true)
		){
			isBST = true;
		}

2.如何判断一棵树是完全二叉树?

概念:

什么是完全二叉树?

完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2^(h-1) 个节点。

方法:宽度优先遍历——使用队列
  • 任何一个节点,如果有右节点没有左节点,则直接return false;
  • 在条件1不违规的情况下,如果遇到了第一个左右子不全的节点,那遍历后面的节点时,后续皆为叶节点;
//判断是否为完全二叉树  20220329
	public static boolean isCBT(Node head){
		if(head == null){
			return true;
		}
		LinkedList<Node> queue = new LinkedList<>();
		boolean leaf = false;
		Node l = null;
		Node r = null;
		queue.add(head);
		while (!queue.isEmpty()){
			head = queue.poll();//从队列中弹出一个还在
			l = head.left;
			r = head.right;
			if(//如果遇到了不双全的节点之后,这个节点居然不为空,不为叶节点(有左孩子或者左孩子)
					(leaf && ( l!=null || r != null))
					||
							(l == null || r != null)//有右边的孩子没有左边的孩子直接返回false
			){
				return false;
			}
			if ( l != null){
				queue.add(l);
			}
			if ( r != null){
				queue.add(r);
			}//如果左右孩子不为空,就将叶节点标记为true
			if ( l == null || r == null){
				leaf = true;//一旦改为true 就不会改为false了
			}
		}
		return true;
	}

3.如何判断一棵树是否为满二叉树

概念:

满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。

解法:(笨笨的麻烦的解法)
  • 先求二叉树的最大深度 再求二叉树的节点个数
  • 深度 L和 个数N 满足一个数学关系(N = 2的L次方-1)如果满足则return true
代码实现
public static boolean isF(Node head){
		if (head == null){
			return true;
		}
		Info data = f(head);
		return data.nodes == (1<<data.height-1);
	}
	//递归信息体中定义了两个参数 第一为二叉树的高度 第二为二叉树的个数
	public static class Info{
		public int height;//二叉树的高度
		public int nodes;//二叉树的节点个数
		public Info(int h,int n){
			height = h;
			nodes =n;
		}
	}
	public static Info f(Node x){
		if(x == null){
			return new Info(0,0);
		}
		Info leftData = f(x.left);
		Info rightData = f(x.right);
		int height = Math.max(leftData.height,rightData.height)+1;
		int nodes = Math.max(leftData.nodes,rightData.nodes)+1;
		return new Info(height,nodes);
	}

4.如何判断一棵树是否为平衡二叉树

概念

平衡二叉搜索树:又被称为AVL(Adelson-Velsky and Landis)树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

解题思路

判断条件:这三个条件必须同时满足

  1. 左树为平衡二叉树

  2. 右树为二叉树

  3. 左高和右高的差不为1

我们需要得到这样的信息:

左树是否为平衡二叉树?高度是多少?

右树是否为平衡二叉树?高度是多少?

可以看出,这道题适合使用递归的方法!

解题思路
public static boolean isBalanced(Node head){
   	return  process(head).isBalanced;
   }
   //定义递归函数的返回值
   public static class ReturnType{
   	public boolean isBalanced;
   	public int height;
   	//构造函数
   	public ReturnType(boolean isB,int hei){
   		isBalanced = isB;
   		height = hei;
   	}
   }
   //x也需要返回两个值
   //上面用ReturnType类 做来做process类的返回信息 这样就能递归从下往上知道每棵树是否平衡
   public static ReturnType process(Node x){
   	if(x == null){//空树的时候也需要有返回值
   		return new ReturnType(true,0);
   	}
   	//这里括号内的内容先当黑盒处理
   	ReturnType leftdata = process(x.left);
   	ReturnType rightdata = process(x.right);

   	int height = Math.max(leftdata.height,rightdata.height)+1;//这里说实话不是特别明白
   	//上面提到的三个条件 左树为平衡树 右树为平衡树 左右两个树的高度差为1
   	boolean isbalanced = leftdata.isBalanced && rightdata.isBalanced && Math.abs(leftdata.height-rightdata.height)<2;
   	return new ReturnType(isbalanced,height);
   }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值