二叉树已知前序中序求后序(超简单)(java)

首先解题思路来自b站某高手,思路清奇,请看官先看视频:

无脑秒解!已知先/后序遍历与中序遍历,求后/先序遍历。_哔哩哔哩_bilibili大佬轻喷,这个题做很简单,但是想做的快做的准应该没有比这更快的了。原理是什么,问就是不知道,你们看我这破书是20年的就应该知道我是菜鸡了。随便找几个题试一下我保证你对。https://www.bilibili.com/video/BV1Xu411d7qf?spm_id_from=333.999.0.0

老铁们,看完视频是否有茅塞顿开的感觉 XD

这个方法强悍之处就在,y轴可以用前序,后序(倒过来写),层序。一行代码都不用改的情况下,可以解三种题(已知前、中序求后序;已知中、后序求前序;已知层、中序求前或后序)!

代码见下,主要是buildTreeNode()方法,完美还原了视频的解题思路,老铁们悟了记得点个赞,谢啦。

import java.util.*;

public class Demo二叉树 {

	/**二叉树类
	 *data 根节点
	 *left 左子树
	 *right 右子树
	 */
	static class TreeNode {
		public String data;
		public TreeNode left;
		public TreeNode right;

		public TreeNode(String data) {
			super();
			this.data = data;
		}
	}
	
	/**
	 * 二叉树,根据前序遍历和中序遍历求后序遍历
	 * @param args
	 */
	public static void main(String[] args) {
		String qian = "ABCDEFGHIJ";// 前序
		String zhong = "CBAFEDIHJG";// 中序
		TreeNode treeNode = new TreeNode(qian.substring(0, 1));//根节点
		buildTreeNode(qian, zhong, treeNode, null, null);//补全treeNode的子树
		List<String> resultList = new ArrayList<String>();
		houxu(treeNode, resultList);//解析treeNode结构,按后序遍历出来
		System.out.println(resultList.toString());//[C, B, F, E, I, J, H, G, D, A]
	}

	/**
	 * 构建二叉树结构
	 * @param qian 前序字符串 或 后序字符串倒写 或 层序字符串 (兼容3种顺序)
	 * @param zhong 中序字符串
	 * @param tn 二叉树(上层递归的子树)
	 * @param leftLimit 中序字符串取值范围,左边界
	 * @param rightLimit 中序字符串取值范围,右边界
	 */
	public static void buildTreeNode(String qian, String zhong, TreeNode tn, Integer leftLimit, Integer rightLimit) {
		int indexQian = qian.indexOf(tn.data);//tn的根节点在前序中的位置
		int indexZhong = zhong.indexOf(tn.data);//tn的根节点在中序中的位置
		for (int i = indexQian + 1; i < qian.length(); i++) {//在前序字符串中由前往后找tn的子树
			String iString = String.valueOf(qian.charAt(i));//当前要找的根节点字符
			int j = zhong.indexOf(iString);//在中序字符串中的位置
			//如果左子树没赋值,且 中序字符串中该字符在tn的根节点左边,且 在左边界的右边,则 找到左子树(的根节点)。
			if (tn.left == null && j < indexZhong && ((leftLimit != null && j > leftLimit) || leftLimit == null)) {
				tn.left = new TreeNode(iString);
				buildTreeNode(qian, zhong, tn.left, leftLimit, indexZhong);//递归时更新右边界,因为中序字符串中,一个二叉树的左子树的所有子树都在这个二叉树的左边。
			//如果右子树没赋值,且 中序字符串中该字符在tn的根节点右边,且 在右边界的左边,则 找到右子树(的根节点)。
			} else if (tn.right == null && j > indexZhong && ((rightLimit != null && j < rightLimit) || rightLimit == null)) {
				tn.right = new TreeNode(iString);
				buildTreeNode(qian, zhong, tn.right, indexZhong, rightLimit);//递归时更新左边界,道理和上面同理。
			}
			if (tn.left != null && tn.right != null) {
				break;//tn的左右子树都找到了就break,找不到也没关系,for循环完后正常结束。
			}
		}
	}
	
	// 前序遍历
	public static void qianxu(TreeNode tn, List<String> list) {
		if (tn == null) {
			return;
		}
		list.add(tn.data);
		qianxu(tn.left, list);
		qianxu(tn.right, list);
	}
 
	// 中序遍历
	public static void zhongxu(TreeNode tn, List<String> list) {
		if (tn == null) {
			return;
		}
		zhongxu(tn.left, list);
		list.add(tn.data);
		zhongxu(tn.right, list);
	}
 
	// 后序遍历
	public static void houxu(TreeNode tn, List<String> list) {
		if (tn == null) {
			return;
		}
		houxu(tn.left, list);
		houxu(tn.right, list);
		list.add(tn.data);
	}
 
	// 层序遍历
	public static void cengxu(List<TreeNode> treeNodes, List<String> list) {
		if (treeNodes.size() == 0) {
			return;
		}
		ArrayList<TreeNode> tns = new ArrayList<TreeNode>();
		for (TreeNode tn : treeNodes) {
			list.add(tn.data);
			if (tn.left != null) {
				tns.add(tn.left);
			}
			if (tn.right != null) {
				tns.add(tn.right);
			}
		}
		cengxu(tns, list);
	}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值