二叉树的中序遍历

Posted treasury

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的中序遍历相关的知识,希望对你有一定的参考价值。

给定一个二叉树,返回它的中序 遍历。

示例:

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

1
2
/
3

输出: [1,3,2]

进阶: 递归算法很简单,你可以通过迭代算法完成吗?

 

题解1:

使用递归,左中右

 

 1 /**
 2  * Definition for a binary tree node.
 3  * public class TreeNode {
 4  *     int val;
 5  *     TreeNode left;
 6  *     TreeNode right;
 7  *     TreeNode(int x) { val = x; }
 8  * }
 9  */
10 class Solution {
11     List<Integer> list=new ArrayList<>();
12 
13     public List<Integer> inorderTraversal(TreeNode root) {
14         inorder(root);
15         return list;
16         
17     }
18     public void inorder(TreeNode root){
19         //递归算法
20         if(root==null)
21             return;
22         inorderTraversal(root.left);
23         list.add(root.val);
24         inorderTraversal(root.right);
25     }
26 }

时间复杂度 O(n) ,因为递归函数为Tn=2*T(n/2)+1

空间复杂度:最坏情况下需要空间O(n),平均情况为O(logn)。

 

 

题解2:

迭代法,基于栈的遍历(递归本身就是使用的栈,所以利用栈很自然)

 1 public class Solution {
 2     public List < Integer > inorderTraversal(TreeNode root) {
 3         List < Integer > res = new ArrayList < > ();
 4         Stack < TreeNode > stack = new Stack < > ();
 5         TreeNode curr = root;
 6         while (curr != null || !stack.isEmpty()) {
 7             while (curr != null) {
 8                 stack.push(curr);
 9                 curr = curr.left;
10             }
11             curr = stack.pop();
12             res.add(curr.val);
13             curr = curr.right;
14         }
15         return res;
16     }
17 }

时间复杂度 :O(n) 

空间复杂度:O(n)

 

题解3:颜色标记法(一种通用且简明的方法)

该法优点:兼具栈迭代方法的高效,又像递归方法一样简洁易懂,更重要的是,这种方法对于前序、中序、后序遍历,能够写出完全一致的代码。

核心思想如下:

  使用颜色标记节点的状态,新节点为白色,已访问的节点为灰色。

   如果遇到的节点为白色,则将其标记为灰色,然后将其右子节点、自身、左子节点依次入栈。

  如果遇到的节点为灰色,则将节点的值输出。

 1 /**
 2  * Definition for a binary tree node.
 3  * public class TreeNode {
 4  *     int val;
 5  *     TreeNode left;
 6  *     TreeNode right;
 7  *     TreeNode(int x) { val = x; }
 8  * }
 9  */
10 class Solution {
11     
12     class ColorNode {
13         TreeNode node;
14         String color;
15         
16         public ColorNode(TreeNode node,String color){
17             this.node = node;
18             this.color = color;
19         }
20     }
21     public List<Integer> inorderTraversal(TreeNode root) {
22         if(root == null) 
23             return new ArrayList<Integer>();
24             
25         List<Integer> res = new ArrayList<>();
26         Stack<ColorNode> stack = new Stack<>();
27         stack.push(new ColorNode(root,"white"));
28         
29         while(!stack.empty()){
30             ColorNode cn = stack.pop();
31             
32             if(cn.color.equals("white")){
33                 if(cn.node.right != null) stack.push(new ColorNode(cn.node.right,"white"));
34 
35                 stack.push(new ColorNode(cn.node,"gray"));
36 
37                 if(cn.node.left != null)stack.push(new ColorNode(cn.node.left,"white"));
38             }else{
39                 res.add(cn.node.val);
40             }
41         }
42         
43         return res;
44     }
45 }

 

这种方法比较通用,简单好记

时间复杂度 :O(n) 

空间复杂度:O(n)

 

 

题解4:莫里斯遍历(了解)

 

若current没有左子节点

  a. 将current添加到输出

  b. 进入右子树,亦即, current = current.right

否则

  a. 在current的左子树中,令current成为最右侧节点的右子节点

  b. 进入左子树,亦即,current = current.left

class Solution {
    public List < Integer > inorderTraversal(TreeNode root) {
        List < Integer > res = new ArrayList < > ();
        TreeNode curr = root;
        TreeNode pre;
        while (curr != null) {
            if (curr.left == null) {
                res.add(curr.val);
                curr = curr.right; // move to next right node
            } else { // has a left subtree
                pre = curr.left;
                while (pre.right != null) { // find rightmost
                    pre = pre.right;
                }
                pre.right = curr; // put cur after the pre node
                TreeNode temp = curr; // store cur node
                curr = curr.left; // move cur to the top of the new tree
                temp.left = null; // original cur left be null, avoid infinite loops
            }
        }
        return res;
    }
}

 


链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal

以上是关于二叉树的中序遍历的主要内容,如果未能解决你的问题,请参考以下文章

二叉树的中序遍历

java刷题--94二叉树的中序遍历

java刷题--94二叉树的中序遍历

java刷题--94二叉树的中序遍历

java刷题--94二叉树的中序遍历

为啥树的后根遍历对应二叉树的中序遍历