vlambda博客
学习文章列表

算法系列二之树:二叉树的前中后序遍历

大家好呀,我是饲养员,今天给大家分享一个简单的算法题,树问题:二叉树的深度遍历


144. 二叉树的前序遍历

难度:简单


给你二叉树的根节点 root ,返回它节点值的 前序 遍历。


示例 1:

输入:root = [1,null,2,3]

输出:[1,2,3]


示例 2:

输入:root = []

输出:[]


示例 3:

输入:root = [1]

输出:[1]


示例 4:

输入:root = [1,2]

输出:[1,2]


示例 5:

输入:root = [1,null,2]

输出:[1,2]


解:

/** * 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) { if(root == null){ return Collections.EMPTY_LIST; } List<Integer> list = new ArrayList<>(); // 前序遍历:根左右 list.add(root.val); list.addAll(preorderTraversal(root.left)); list.addAll(preorderTraversal(root.right)); return list; }}


用递归写非常简单,那么中序遍历也是第23行和24行对换即可,后序也是如此,由于这是一道简单题,我们需要尝试非递归的写法,可是思路应该怎样呢?我遍历到的节点不一定就是要的结果顺序呀,如果能够控制先进的能够后出就好了,那么这种数据结构是什么呢?栈(Stack)

来,我们试一下用非递归写一下,代码如下:

class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> list = new LinkedList<>(); // 初始化一个栈,用来存放临时数据 Stack<TreeNode> stack = new Stack<>(); TreeNode tree = root; // 如果当前节点已经空或者栈为null,则跳出循环 while(tree != null || !stack.empty()){ // 正常场景下,当前树不为null,能够继续循环的情况 while (tree != null) { list.add(tree.val); stack.add(tree); tree = tree.left; } // 接下来分tree == null, stack还没有完全弹出的情况,只要直接弹出即可 tree = stack.pop(); // 根节点和左节点分别完成,剩下右节点 tree = tree.right; } return list; }}

那么中序遍历呢?

class Solution { public List<Integer> inorderTraversal(TreeNode root) { List<Integer> list = new LinkedList<>(); Stack<TreeNode> stack = new Stack<>(); TreeNode tree = root; while(tree != null || !stack.empty()){ if (tree != null) { stack.add(tree); tree = tree.left; } else { tree = stack.pop(); list.add(tree.val); tree = tree.right; } } return list; }}

总结

其实非递归方式无非就是用一个栈去临时存放树,从而达到控制存放树存放顺序这么一个作用,其实栈的用法也很简单,pop是弹出元素,add是放入元素,栈是先进后出的,前序遍历是根左右,中序是左根右,知道这些基本的概念后,解题就很容易。


好了,本期的饲养员投喂完毕,下次见!