如下提供两大类——递归和栈,实现二叉树的中序遍历。
每一大类都提供多种模式——leetcode答题模式、IDEA运行模式。
其中leetcode答题模式答案可以参考官方,本文将只对该部分简略描述。
一、递归
模式一: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 List<Integer> inorderTraversal(TreeNode root) { //只需要调用此函数,且只需要传入root一个参数
List<Integer> res = new ArrayList<Integer>();//创建res list保存结果
inOrder(root, res);//调用递归函数,注意参数为root和保存结果的res
return res;//返回结果
}
public void inOrder(TreeNode root, List<Integer> res){
if(root == null) return;//日常判空
inOrder(root.left, res);//一直循环遍历root.left,直到最内层root为null,则一层层往外剥
res.add(root.val);//上一行遍历到最内层开始执行该步,将节点存入res
inOrder(root.right, res);//上上行执行到最内层执行一次add后,执行该步,然后执行上上行往外剥
}
}
模式二:idea,打印res结果出来(以list格式)
import java.util.ArrayList;
import java.util.List;
class Solution{
//定义外部类——Node
public static class Node{
int val;
Node left;
Node right;
Node(int val) {this.val = val;}
}
//创建中序方法
public static void inOrderTraversal(Node root) {
List<Integer> res = new ArrayList<Integer>();
inOrder(root, res);
System.out.println(res);//该步直接将res最终结果打印
}
//创建递归方法
public static void inOrder(Node root, List<Integer> res) {
if (root == null) return;
inOrder(root.left, res);
res.add(root.val);
inOrder(root.right, res);
}
public static void main(String[] args) {
//初始化二叉树
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.left.left.left = new Node(8);
root.left.left.right = new Node(9);
root.right.left = new Node(6);
root.right.right = new Node(7);
inOrderTraversal(root);
}
}
模式三:不需要通过res list,而是直接打印出来(以字符格式)
class Solution{
//定义外部类——Node
public static class Node{
int val;
Node left;
Node right;
Node(int val) {this.val = val;}
}
//创建中序方法
public static void inOrderTraversal(Node root) {
if (root == null) return;
inOrderTraversal(root.left);
System.out.print(root.val + " ");
inOrderTraversal(root.right);
}
public static void main(String[] args) {
//初始化二叉树
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.left.left.left = new Node(8);
root.left.left.right = new Node(9);
root.right.left = new Node(6);
root.right.right = new Node(7);
inOrderTraversal(root);
}
}
二、栈
模式一: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 List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();//创建res保存结果
Deque<TreeNode> stk = new LinkedList<TreeNode>();//借用栈可以回退到root
while (root != null || !stk.isEmpty()) {//分别决定开始和结束
while (root != null) {//开始,whiile条件满足一直执行到不满足为止,if条件满足只执行1次
stk.push(root);
root = root.left;//把root一路向左一直压栈到极左(包括)
}//while执行完说明没有更左了,但是有没有更有需要看下下下行
root = stk.pop();
res.add(root.val);//把极左弹出,并将值add到res
//由于极左没有左节点,所以结束内while走到此处
//极左被保存到res后,根据左中右,此时极左可能为in,需要判断有没有右
//如果有,则把其赋给root,再进行内while的循环
root = root.right;
}
return res;
}
}
模式二:idea保存到res中输出
import javax.swing.tree.TreeNode;
import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
class Solution{
//定义外部类——Node
public static class Node{
int val;
Node left;
Node right;
Node(int val) {this.val = val;}
}
//创建中序方法
public static List<Integer> inOrderTraversal(Node root) {
List<Integer> res = new ArrayList<Integer>();
Deque<Node> stk = new LinkedList<Node>();
while(root != null || !stk.isEmpty()) {
while(root != null) {
stk.push(root);
root = root.left;
}
root = stk.pop();
res.add(root.val);
root = root.right;
}
System.out.print(res);// !就多了这一行
return res;
}
public static void main(String[] args) {
//初始化二叉树
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.left.left.left = new Node(8);
root.left.left.right = new Node(9);
root.right.left = new Node(6);
root.right.right = new Node(7);
inOrderTraversal(root);
}
}
模式三:不使用res存储,直接打印
import java.util.Deque;
import java.util.LinkedList;
class Solution{
//定义外部类——Node
public static class Node{
int val;
Node left;
Node right;
Node(int val) {this.val = val;}
}
//创建中序方法
public static void inOrderTraversal(Node root) {
Deque<Node> stk = new LinkedList<Node>();
while(root != null || !stk.isEmpty()) {
while(root != null) {
stk.push(root);
root = root.left;
}
root = stk.pop();
System.out.print(root.val + " ");
root = root.right;
}
}
public static void main(String[] args) {
//初始化二叉树
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.left.left.left = new Node(8);
root.left.left.right = new Node(9);
root.right.left = new Node(6);
root.right.right = new Node(7);
inOrderTraversal(root);
}
}