• 二叉树的中序遍历


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

    示例:

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

  • 相关阅读:
    MYSQL查看数据表最后更新时间
    linux在终端模拟软件实现文件上传下载
    yum常用操作
    释放Linux占用端口
    CentOS7.3编译安装MariaDB10.2.6
    CentOS7编译安装Nginx1.10.1
    Linux系统安装ActiveMQ时遇到服务无法启动的问题
    需求分析读书笔记(一)
    实用地址分享
    元素居中汇总
  • 原文地址:https://www.cnblogs.com/treasury/p/12600426.html
Copyright © 2020-2023  润新知