zoukankan      html  css  js  c++  java
  • 二叉树的中序遍历

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

    示例:

    输入: [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

  • 相关阅读:
    台州 OJ 3847 Mowing the Lawn 线性DP 单调队列
    洛谷 OJ P1417 烹调方案 01背包
    快速幂取模
    台州 OJ 2649 More is better 并查集
    UVa 1640
    UVa 11971
    UVa 10900
    UVa 11346
    UVa 10288
    UVa 1639
  • 原文地址:https://www.cnblogs.com/treasury/p/12600426.html
Copyright © 2011-2022 走看看