本系列可作为JAVA学习系列的笔记,文中提到的一些练习的代码,小编会将代码复制下来,大家复制下来就可以练习了,方便大家学习。
点赞关注不迷路!您的点赞、关注和收藏是对小编最大的支持和鼓励!
系列文章目录
JAVA数据结构 DAY9 equals、Comparable、Comparator 与 PriorityQueue 深度解析
拓展目录
手把手教你用 ArrayList 实现杨辉三角:从逻辑推导到每行代码详解
Java 中的 hashCode () 与 equals () 核心原理、契约规范、重写实践与面试全解
目录
目录
前言
小编作为新晋码农一枚,会定期整理一些写的比较好的代码,作为自己的学习笔记,会试着做一下批注和补充,如转载或者参考他人文献会标明出处,非商用,如有侵权会删改!欢迎大家斧正和讨论!
本节,我将分享一下二叉树的习题部分,以及思路详解,在力扣 的运行环境,每一题将会附上练题链接,大家点击即可练习!
1.从前序与中序遍历序列构造二叉树
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
题目链接:
105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)


/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
//给定两个整数数组 preorder 和 inorder ,
//其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
public TreeNode buildTree(int[] preorder, int[] inorder) {
return build(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
}
public TreeNode build(int[] preorder,int prestart,int preend,int[] inorder,int instart,int inend){
if(prestart>preend||instart>inend){
return null;
}
int val=preorder[prestart];
TreeNode root=new TreeNode(val);
int rootindex=0;
for(int i=instart;i<inorder.length;i++){
if(val==inorder[i]){
rootindex=i;
break;
}
}
int leftsize=rootindex-instart;
root.left=build(preorder,prestart+1,prestart+leftsize,inorder,instart,rootindex-1);
root.right=build(preorder,prestart+leftsize+1,preend,inorder,rootindex+1,inend);
//✅ 左子树 先序区间
//preStart + 1 ~ preStart + leftSize 跳过根(+1),往后数 leftSize 个,就是左子树全部!
//✅ 右子树 先序区间
//preStart + leftSize + 1 ~ preEnd 左子树结束后,剩下的全是右子树!
//✅ 左子树 中序区间
//inStart ~ rootIndex - 1 根左边全部是左子树!
//✅ 右子树 中序区间
//rootIndex + 1 ~ inEnd 根右边全部是右子树!
return root;
}
}
2.从后序与中序遍历序列构造二叉树
给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
题目链接:
106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
//给定两个整数数组 inorder 和 postorder ,
// 其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
//给定两个整数数组 preorder 和 inorder ,
//其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
public TreeNode buildTree(int[] inorder, int[] postorder) {
return build(inorder,0,inorder.length-1,postorder,0,postorder.length-1);
}
public TreeNode build(int[] inorder,int instart,int inend,int[] postorder,int poststart,int postend){
if(poststart>postend||instart>inend){
return null;
}
int val=postorder[postend];
TreeNode root=new TreeNode(val);
int rootindex=0;
for(int i=instart;i<=inend;i++){
if(val==inorder[i]){
rootindex=i;
break;
}
}
int leftsize=rootindex-instart;
root.left=build(inorder,instart,rootindex-1,postorder,poststart,poststart+leftsize-1);
root.right=build(inorder,rootindex+1,inend,postorder,poststart+leftsize,postend-1);
return root;
}
}
3.根据二叉树创建字符串
给你二叉树的根节点 root ,请你采用前序遍历的方式,将二叉树转化为一个由括号和整数组成的字符串,返回构造出的字符串。
空节点使用一对空括号对 "()" 表示,转化后需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。

题目链接:
606. 根据二叉树创建字符串 - 力扣(LeetCode)
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
//前序遍历顺序:根节点 → 左子树 → 右子树。
//节点处理规则:
//根节点直接拼接数字。
//若存在左子树或右子树,需要用括号包裹子树:
//左子树:无论是否为空,只要存在右子树,就必须用 () 表示空左子树;否则可以省略。
//右子树:只有当右子树非空时,才用括号包裹;空右子树直接省略。
public String tree2str(TreeNode root) {
//空节点
if(root==null){
return "";
}
//左右都无
if(root.left==null&&root.right==null){
return Integer.toString(root.val);
}
//左无
if (root.left==null){
return root.val+"()"+"("+tree2str(root.right)+")";
}
//有左,没有右 ← 加上这一行就完美!
if(root.right==null){
return root.val+"("+tree2str(root.left)+")";
}
//左右都有
return root.val+"("+tree2str(root.left)+")"+"("+tree2str(root.right)+")";
}
}
4.二叉树前序非递归遍历实现
给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

题目链接:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
//二叉树先序遍历的非递归方法
//先压右,再压左!因为栈是后进先出!
//前序:根 → 左 → 右
//栈是后进先出,所以必须先放右孩子,再放左孩子
//这样弹出来的顺序才是:根 → 左 → 右
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> ret=new ArrayList<>();
if(root==null){
return ret;
}
Stack<TreeNode> stack=new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode node=stack.pop();
ret.add(node.val);
if(node.right!=null){
stack.push(node.right);
}
if(node.left!=null){
stack.push(node.left);
}
}
return ret;
}
}
5.二叉树后序非递归遍历实现
给你二叉树的根节点 root ,返回它节点值的 中序 遍历。

题目链接:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
//中序遍历:左 → 根 → 右
//非递归思路(4 句话背会)
//一路向左,全部入栈(走到最左边)
//左边走不动了,再出栈
//出栈时访问(加入结果) → 这就是 “根”
//立刻转向右子树
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> ret=new ArrayList<>();
if(root==null){
return ret;
}
Stack<TreeNode> stack=new Stack<>();
TreeNode cur=root;
while(cur!=null||!stack.isEmpty()){
while(cur!=null){
stack.push(cur);//先入栈 再往左
cur=cur.left;
}
//左边全部的节点都入栈
cur=stack.pop(); //弹出栈顶元素
ret.add(cur.val); //访问根节点
cur=cur.right;//访问右节点
}
return ret;
}
}
6.二叉树后序非递归遍历实现
给你二叉树的根节点 root ,返回它节点值的 后序 遍历。

题目链接:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
//后序 = 根 → 右 → 左 的逆序!
//用前序思路:先压左、再压右 → 得到顺序:根 → 右 → 左
//最后把结果反转 → 就是 左 → 右 → 根(后序)
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> ret=new ArrayList<>();
if(root==null){
return ret;
}
Stack<TreeNode> stack=new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode node=stack.pop();
ret.add(node.val);
if(node.left!=null){
stack.push(node.left);
}
if(node.right!=null){
stack.push(node.right);
}
}
Collections.reverse(ret);
return ret;
}
}
总结
以上就是今天要讲的内容,本文简单记录了java数据结构,仅作为一份简单的笔记使用,大家根据注释理解,您的点赞关注收藏就是对小编最大的鼓励!
&spm=1001.2101.3001.5002&articleId=159215425&d=1&t=3&u=3276b2bc11394e8a95987a1f17380e91)
333

被折叠的 条评论
为什么被折叠?



