94. 二叉树的中序遍历
94. 二叉树的中序遍历
一、题目描述
给定一个二叉树,返回它的中序 遍历。
示例:
输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
二、解题思路
该题目旨在探讨递归与迭代的关系,递归是指在函数定义中调用函数自身的方法。递归法主要用于解决三中问题:
- 数据的定义是按照递归定义的(Fibonacci函数)
- 问题解法是按递归算法实现(Hanoi问题)
- 数据的结构形式是按递归定义(二叉树)
迭代是指重复执行一系列运算步骤,从前面的量依次求出后面的量的过程。
一般来说,递归能解决的问题采用迭代法同样能够解决。因为递归采用了系统栈保存了任务运行状态,从而开启下一任务,当任务结束后即可恢复前一任务运行状态继续运行。迭代+栈组合亦可达到此种效果,使用栈保存迭代中运行的相关运行信息即可。
一、递归
1、解题思路
中序遍历(递归实现)
2、代码
List<Integer> list = null; public List<Integer> inorderTraversal(TreeNode root) { list = new ArrayList<>(); preorder(root); return list; } public void inorder(TreeNode root) { if(root != null){ list.add(root.val); preorder(root.left); preorder(root.right); } }
二、系统栈迭代
1、解题思路
中序遍历(系统栈实现)
模拟递归中的系统栈存储执行环境的过程;通过自定义数据结构Command
存储每个命令的含义,如果message
是print
,则直接打印该节点的值;如果message
是go
,则继续遍历该节点的左右子节点。以栈的方式存储每一条命令,根据左右子节点入栈以及打印节点值的先后来进行中序遍历。
2、代码
static class Command { String message; TreeNode node; Command(String message, TreeNode node) { this.message = message;this.node = node; } } //迭代法 public List<Integer> inorderTraversal(TreeNode root) { List<Integer>list = new ArrayList<>(); if(root==null)return list; Stack<Command>stack = new Stack<>(); stack.push(new Command("go",root)); while (!stack.isEmpty()){ Command cur = stack.pop(); if(cur.message.equals("print")){ list.add(cur.node.val); }else{ //栈 先进后出 if(cur.node.right!=null)stack.push(new Command("go",cur.node.right)); stack.push(new Command("print",cur.node)); if(cur.node.left!=null)stack.push(new Command("go",cur.node.left)); } } return list; }
三、栈迭代
1、解题思路
中序遍历(栈实现)
以null为标志,判定是否需要进行遍历左子树至尽头!!!
2、代码
/** * 以null为标志,若栈弹出的是null,则继续弹出下一个作为根节点,将其右子节点入栈 * 若栈弹出的非null,则遍历其左子树直至入栈为null */ public List<Integer> inorderTraversal1(TreeNode root) { List<Integer>list = new ArrayList<>·(); if(root==null)return list; Stack<TreeNode>stack = new Stack<>(); stack.push(root); while (!stack.isEmpty()){ TreeNode cur = stack.peek(); while (cur!=null){//遍历左子树至尽头,全部入栈(包括null) stack.push(cur.left); cur = stack.peek(); } stack.pop();//空节点出栈(已遍历左子树的节点最终会入栈null,作为标志) if(!stack.empty()){//访问结点,向右一步 cur = stack.pop();//(代表该节点为未遍历至尽头的节点) list.add(cur.val); if(cur!= null)stack.push(cur.right);//添加右子节点(若为null,则后续直接弹出,否则后续遍历其左子树) } } return list; }
LeetCode题解 文章被收录于专栏
收录leetcode题解,专注于算法练习。