有快一周没更新了,主要也比较忙,另外再写一个新的文章方向,文章是自己没经历的,故而进度比较慢。今天先写一个二叉树点数据结构练习,让自己多熟悉熟悉。
前置知识:
- 1.三种遍历方式
前序遍历:根节点 - 左子树 - 右子树。
中序遍历:左子树 - 根节点 - 右子树
后序遍历:左子树 - 右子树 - 根节点。
- 2.定义一个二叉树
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;
}
}
- 例题解析,如:root = [1, null, 2, 3]
中序遍历的顺序是左节点→根节点→右节点,所以先是根节点1,再到右节点。但是节点2是有左子节点的,所以先遍历左子树3,再回到2。最终结果[1,3,2]
编写代码:
针对二叉树的遍历,可以采用两种不同的方法。
方法一:迭代
import java.util.ArrayList;
import java.util.List;
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
//创建一个整数列表,用于存储中序遍历的结果
List<Integer> result=new ArrayList<>();
//递归:将问题分解为更小的子问题,然后使用递归函数。
//中序遍历,先遍历左子树,然后访问根节点,再遍历右子树。
//inorderSolve接受根节点root作为参数,返回列表用于存储遍历的结果。
inorderSolve(root,result);
return result;
}
private void inorderSolve(TreeNode node, List<Integer> result) {
//如果当前节点为空,直接返回;表示递归的终止条件,遍历到子节点时会返回上一级
if(node==null){
return;
}
//
inorderSolve(node.left,result);
result.add(node.val);
inorderSolve(node.right,result);
}
}
方法二:栈
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
//创建result的整数列表,用于存储中序遍历的结果
List<Integer> result=new ArrayList<>();
//创建栈,用于迭代存储节点,模拟递归
Stack<TreeNode> stack=new Stack<>();
//将current初始化为传入的根节点root,表示当前正在处理的节点
TreeNode current=root;
//当前节点不为空,或栈不为空,保证遍历可以继续
while (current != null || !stack.isEmpty()){
while (current != null){
//将左子节点押入栈中,以便之后访问右子树
stack.push(current);
current=current.left;
}
//无法向左遍历时,从栈中弹出节点,赋给current
current=stack.pop();
//将当前节点值加入result
result.add(current.val);
//再更新为右节点,遍历右子树
current=current.right;
}
return result;
}
}