二叉树的递归套路简介集合

二叉树递归

二叉树结构 中序遍历 查找后继节点

Class Node{
	V value;
	Node left;
	Node right;
	Node parent;
}

给你二叉树中的某个节点 ,返回该节点的后继节点

中序遍历顺序 左 头 右
中序遍历过程中 该节点中序遍历的下一个节点
递归序 表明每个节点访问三次

  • 如果该节点是当前子树的左孩子 则后继节点就是其父节点。
  • 如果该节点是当前子树的右孩子 向上寻找 出现父节点为曾父节点的左孩子时候
    则该曾父节点就是该节点的后继节点 整颗树的最右节点 则其没有后继节点 中序 寻找后继节点
public static Node gerSuccessorNode(Node node){
	if(node == null)
		return node;
	if(node.right != null){
		return getLeftMost(node.right);   //  如果有右树  则寻找右树的最左孩子
	} else {  // 无右子树
		Node parent = node.parnet;
		//  表示当前节点是父亲节点的右孩子  
		//  parent.left !=nofe  二者等效 parent.right == node;
		//  该循环寻找左孩子  不符合则跳出 表明找到该节点的后继节点	
		while( parent != null && parent.left != node){  // 当前节点是其父亲节点右孩子
			node =parent;   // 边界考虑  parent!= null 保证此处不会出现空指针异常
			parent = node.parent;
		}
		return parent;
	}
}

public static Node getLeftMost(Node node){
	if(node == null)
		return node;
	while(node.left != null){
		node =node.left;  //  一直访问左边的子树
	}
	return node;
}

后继和前驱 相似

可以用递归模拟树 不需要建立整颗树 (递归栈) O(n)
有规律 左树节点都是凹 右树节点多是凸 头节点默认也是凸

	  凹
凹	          	 凸 
 凹                    凸            凹	         凸

递归站 模拟树实现

public static void printProcess(int i, int N, boolean down){
	if( i > N)
		return ;
	printProcess(i+1, N ,true);
	System.out.println(down ? "凹" : "凸")printProcess(i+1, N ,false);
}

public static void main(String[] args){	
	int N=3;
	printAllfold(N);
}

二叉树的递归套路

解决绝大多数的二叉树问题尤其是树形dp问题
本质利用递归遍历二叉树的便利性

二叉树 递归套路

  • 假设以X节点为头
  • 假设可以向X左树和X右树要任何信息 在上一步的假设下 套路以X为节点的树 得到答案的可能性
  • 列出所有的可能性后
  • 确定到底需要左数和右树要什么样的信息 把左数信息和右树信息求全集 就是任何一颗子树都需要返回的信息S 递归函数都返回S
  • 每一颗子树都这么要求 写代码 在代码中考虑如何把左树的信息和右树信息整合出整颗树的信息

给定一颗二叉树的头节点head 返回这颗二叉树是不是平衡二叉树
平衡二叉树的定义
(整体都得平衡) 左子树平衡 右子树平衡 左右子树的高度差绝对值小于1

// 主函数 像其中传入 head 最终获取对应的isBalaced 进行判断是否是平衡树

public static boolean isBalanced2(Node he ad){
	return process2(head).isBalaced;
}

左右要求一样   Info 信息返回的结构体

//  设置一个合适的结构体变量
public static class Inof{
	public  boolean isBalaced;
	public  int height;
	
	public Info(boolean b , int h){
		isBalaced = b;    // 判断平衡性
		height = h;        // 求取子树的高度
	}
}

//    对函数进行返回  自定义 Inof返回类型
public static  Inof process2( Node X){
	if ( X== null ){
		return   new Info(true , 0);
	}

	  //   进行 返回 子树的两个值    递归
	Info leftInfo  = process2(X.left);
	Info leftInfo  = process2(X.right);
	

	 //   需要该信心进行判断 子树是否是平衡的
	int height = Math.max(leftInof.height ,rightInfo.height ) +1	;    // 用这个语句进行判断每个子树对应的高度  获取对应的 leftlnfo.left 和 rightlnfo.right高度差
	
	//   平衡性的判断    保证左右子树的平衡性 且 二者的高度差
	
	boolean isBalanced = true;  //  默认是一个平衡树
	if( !leftInfo.isBalanced || !right.isBalanced || Math.abs(leftInfo.height - rightInfo.left)>1){
		isBalanced = false;
	}
	
	return new Info(isBalanced, hegiht);
}

给定一颗二叉树的头节点head, 任何两个节点之间都存在距离 返回整颗二叉树的最大距离
判断和当前x节点 是否有关

存在 两种可能
x无关
max 左最大距
右最大距
x有关
做高+1+右高

public static int maxDistance(Node  head){
	return process(head).maxDistance;
}
//  树型 动态规划   通过自己的左右树进行 提供信息  自己进行整合为自己的信息   并且向上返回新的信息
//   结构体的定义
//  左右树的之间的最大距离  保留   并且寻找到自身的树高

public static calss Info{
	public int maxDistance;  // 整颗树的最大距离
	public int  height;            //  整颗树的高度
	
	public Info(int dis, int h){
		maxDistance = dis;
		height =h;
	}
}	
//  在一个节点中  返回两个值  一个树高  保留当前位置 寻找另外距离长的左右子树的树高
public static Info process(Node X){
	if(X ==null)
		return new Info(0,0);	
	
	Info  leftInfo = process(X.left);
	info  rightInfo =process(X.right);
	
	int height = Math.max(leftInfo.height , rightInfo.hegiht )+1;
	int maxDistance= Math.max(Math.max(leftInfo.maxDistance ,rightInfo.maxDistance), (leftInfo,height +rightInfo.height +1));
	
	return new Info(maxDistance , height);
}

给定一颗二叉树的头节点head 返回这颗二叉树中最大二叉搜素子树的节点数

搜索二叉树这棵树上没有重复的值 左树《 头节点 《右树 且 其中的每棵子树的都符合。

左树 最大子搜size boolean isallbst max
右树 最大子搜size boolean isallbst min

左右树 信息不一样 求全集

存在二者可能 要么二叉搜索树联系着当前节点
要么二叉搜索树于当前节点无关 只和当前节点的左右子树有关

// 任何子树 返回四个信息

public static class Inof{	
	public boolean isAllBST;
	public int maxSubBSTSize;
	public int min;
	public int max;

	public Info(boolean is , int size, int mi , int ma){
		isAllBST = is;
		maxSubBSTSize =size;
		min = mi;
		max =ma;
	}
}

public static Info process(Node X){
	if(x == null ){
		return null;
	}
	Info leftInfo = process(X.lfet);
	Info rightsInfo = process(X.right);
	
	public int min=X.value;
	public int max=X.value;

	//     提前进行判断 是否为空
	if(leftinfo != null){
		min = Marth.min(min, leftInfo.min);
		max = Marth.max(max, leftInfo.max);
	}

	if(rightinfo != null){
		max = Marth.max(max, righeInfo.max);
		min = Marth.min(min, righeInfo.min);
	}


	public int maxSubBSTSize=0if(lfetInfo != null){
		maxSubBSTSize = leftInfo.maxSubBSTsize;
	}
	if(rightInfo != null){
		maxSubBSTSize = Math.max(maxSubBSTSize , rightInfo.maxSubBSTSize);
	}

	public boolean isAllBST=false;

	if(        // 左树整体需要是搜索二树  
	            (leftInfo == null ? true : leftInfo.isAllBST)
	           &&(rightInfo == null ?true :rightInfo.isAllBST)
	           &&
		// 左树最大值<x
		(lfetInfo == null ? true : lfetInfo.max<X.value)
	             &&
		(rightInfo == null ? true : rightInfo.min>X.value)
		){   //  以上的判断需要全部成立

			maxSubBSTSize = (leftInfo== null ? 0 : leftInfo.maxSubBSTSize)+(rightInfo== null ? 0 : rightInfo.maxSubBSTSize) +1;
			isAllBST = true;
		}
	return new Ifo(isAllBST, maxSubBSTSize , ,min ,max);
}

二叉树的递归套路

  1. 假设以x节点为头 假设可以向x左树和x右树要任何信息
  2. 在上一步的假设下 讨论以x为头节点的树 得到答案的可能性 (判断当前的节点 信息是否受之后的影响)
  3. 列出所有的可能性后 确定到底需要向左树和右树要什么样的信息
  4. 把左树信息和右树信息求全集 就是任何一颗子树都需要返回的信息S
  5. 递归函数都返回S 每一颗子树都这么要求
  6. 写代码 在代码中考虑如何把左树的信息和右树的信息整合出整颗树的信息

派对的最大快乐值

一个下级只能对应一个上级

如果某个员工来了 那么这个员工的所有的直接下级都不能来 (直接上级来了 其直接下级就不能来了)
排队的整体快乐之是所有到场员工快乐值的累加
你的目标是让快乐整体值尽量最大
给定一颗多叉树的头节点 请返回排队的最大快乐值

员工信息的定义如下:

class Employee{
	public int happy; //  这名员工可以带来的快乐值
	List<Employee> nexts;// 这名员工有直接下级
	
	public Employee(int h){
		happy = h;
		nexts = new ArrayList<>();
	}
}


public static int maxHappy1(Employee boss){
	if(boss == null){
		return 0;
	}
	retrun process1(boss, flase);
}


//   表示头节点 来或者不来时的最大快乐值
	对于任何子树 都要返回 当头节点来的时候最大快乐值
		当头节点不来的时候最大快乐值	
public static class info{
	public int yes;
	public int no;
	
	public Info(int y,int n){
		yes=y;
		no =n;
	}
}

public static int process2(Employee x){
	if(x.next.isEmpyty()){  // 表示如果只有你一个人  你来则返回自身的快乐值 否则返回0
		return new Info(x.happy , 0);
	}
	
	int yes = x.happy;  // 如果x来  则先获取 x的当前happy
	int no =0;
	for(Employee next :x.nexts){
		Info nextInfo = process2(next);   // 循环 调用当前的节点的下级节点
		yes+=nextInfo.no;
		no+=Math,max(nextInfo.yes , nextInfo.no);
	}
	return new Info(yes,no);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二叉树是一种常见的数据结构,在递归算法中也有很多应用。创建二叉树递归算法可以分为前序遍历和中序遍历两种方式。 前序遍历方式下,我们按照“根-左-右”的顺序来构建二叉树。具体步骤如下: 1. 如果输入的节点值为null,则返回空节点。 2. 创建一个新的节点,将其值设置为当前的节点值。 3. 递归调用函数,将左子树的根节点设置为当前节点的左子节点。 4. 递归调用函数,将右子树的根节点设置为当前节点的右子节点。 5. 返回当前节点。 中序遍历方式下,我们按照“左-根-右”的顺序来构建二叉树。具体步骤如下: 1. 如果输入的节点值为null,则返回空节点。 2. 递归调用函数,将左子树的根节点设置为当前节点的左子节点。 3. 创建一个新的节点,将其值设置为当前的节点值。 4. 递归调用函数,将右子树的根节点设置为当前节点的右子节点。 5. 返回当前节点。 下面是一个示例代码,以前序遍历方式为例: ``` class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } public class Solution { public TreeNode buildTree(int[] preorder, int[] inorder) { return build(preorder, inorder, 0, preorder.length - 1, 0, inorder.length - 1); } private TreeNode build(int[] preorder, int[] inorder, int preStart, int preEnd, int inStart, int inEnd) { if (preStart > preEnd || inStart > inEnd) { return null; } int rootVal = preorder[preStart]; int index = 0; for (int i = inStart; i <= inEnd; i++) { if (inorder[i] == rootVal) { index = i; break; } } TreeNode root = new TreeNode(rootVal); root.left = build(preorder, inorder, preStart + 1, preStart + index - inStart, inStart, index - 1); root.right = build(preorder, inorder, preStart + index - inStart + 1, preEnd, index + 1, inEnd); return root; } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值