训练营十四天(二叉树的遍历)

二叉树的递归遍历

java 复制代码
树的定义
public class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    
    public TreeNode() {}
    
    public TreeNode(int val) {
        this.val = val;
    }
    
    public TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

递归三要素

  • 确定递归函数的参数和返回值
  • 确定终止条件
  • 确定单层递归的逻辑

1.前序遍历 根左右

144.二叉树的前序遍历(opens new window)

java 复制代码
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<Integer>();
        preorder(root, result);
        return result;
    }

    private void preorder(TreeNode root,  List<Integer> result){
        if(root == null)
            return;
        result.add(root.val);
        preorder(root.left,result);
        preorder(root.right,result);
    }
}

2.后序遍历 左右根

145.二叉树的后序遍历(opens new window)

java 复制代码
class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<Integer>();
        postorder(root, result);
        return result;
    }

    private void postorder(TreeNode root,  List<Integer> result){
        if(root == null)
            return;
        postorder(root.left,result);
        postorder(root.right,result);
        result.add(root.val);
    }
}

3. 中序遍历 左根右

94.二叉树的中序遍历

java 复制代码
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<Integer>();
        inorder(root, result);
        return result;
    }

    private void inorder(TreeNode root,  List<Integer> result){
        if(root == null)
            return;
        inorder(root.left,result);
        result.add(root.val);
        inorder(root.right,result);
    }
}

二叉树的迭代遍历

1.前序遍历 根左右

使用栈,因为栈是后入先出,所以使用栈来记录结点,先押入跟结点,在押入右结点和左节点,按照出栈顺序访问元素

java 复制代码
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
		List<Integer> result = new ArrayList<>();
		if (root == null)
			return result;
		Stack<TreeNode> stack = new Stack<>();
		stack.push(root);
		while (!stack.isEmpty()){
			TreeNode temp = stack.pop();
			//left后入栈会先出栈,因为是根左右
			result.add(temp.val);
			if (temp.right != null)
				stack.push(temp.right);
			if (temp.left != null)
				stack.push(temp.left);
		}
		return result;
    }
}

2.后序遍历 左右根

与前序遍历基本一致

  • 后序遍历顺序 左-右-中
  • 入栈顺序:中-左-右
  • 出栈顺序:中-右-左
  • 最后翻转结果(一定要记得翻转结果,否则得到的是根右左)
java 复制代码
class Solution {
	public List<Integer> postorderTraversal(TreeNode root) {
		List<Integer> result = new ArrayList<>();
		if (root == null)
			return result;
		Stack<TreeNode> stack = new Stack<>();
		stack.push(root);
		while (!stack.isEmpty()){
			TreeNode temp = stack.pop();
			result.add(temp.val);
			if (temp.left != null){
				stack.push(temp.left);
			}
			if (temp.right != null){
				stack.push(temp.right);
			}
		}
		Collections.reverse(result);
		return result;
	}
}

3. 中序遍历 左根右

单独的思路,因为不能先将根压入栈,那么如果先将left入栈会导致指针的丢失,所以要先找到左子树为空的,也就是下一个元素就是当前的栈顶,即当前子树的根结点

java 复制代码
class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
		List<Integer> result = new ArrayList<>();
		if (root == null)
			return result;
		TreeNode cur = root;
		Stack<TreeNode> stack = new Stack<>();
		while (!stack.isEmpty() || cur != null){
			if (cur != null){//此时要找到左子树的底部
				stack.push(cur);
				cur = cur.left;
			}else {//当前结点没有了左子树,那么当前没有左子树的跟结点就是栈顶
				cur = stack.pop();
				result.add(cur.val);
				cur = cur.right;
			}
		}
		return result;
    }
}
相关推荐
陈果然DeepVersion21 小时前
Java大厂面试真题:Spring Boot+Kafka+AI智能客服场景全流程解析(十)
java·spring boot·ai·kafka·面试题·向量数据库·rag
但要及时清醒1 天前
ArrayList和LinkedList
java·开发语言
一叶飘零_sweeeet1 天前
从测试小白到高手:JUnit 5 核心注解 @BeforeEach 与 @AfterEach 的实战指南
java·junit
摇滚侠1 天前
Spring Boot3零基础教程,Reactive-Stream 四大核心组件,笔记106
java·spring boot·笔记
Z3r4y1 天前
【代码审计】RuoYi-3.0 三处安全问题分析
java·web安全·代码审计·ruoyi-3.0
与遨游于天地1 天前
Spring解决循环依赖实际就是用了个递归
java·后端·spring
陈果然DeepVersion1 天前
Java大厂面试真题:Spring Boot+微服务+AI智能客服三轮技术拷问实录(六)
java·spring boot·redis·微服务·面试题·rag·ai智能客服
BeingACoder1 天前
【SAA】SpringAI Alibaba学习笔记(一):SSE与WS的区别以及如何注入多个AI模型
java·笔记·学习·saa·springai
DolphinScheduler社区1 天前
真实迁移案例:从 Azkaban 到 DolphinScheduler 的选型与实践
java·大数据·开源·任务调度·azkaban·海豚调度·迁移案例