zoukankan      html  css  js  c++  java
  • 每天1题算法题(1)-二叉树的中序遍历

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

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


    1.最简单也是最直接的,直接用递归算法实现
    class Solution {
        public List<Integer> inorderTraversal(TreeNode root) {
                List<Integer> result = new ArrayList();
                dfs(root,result);
                  return result;
        }
    
        public void dfs(TreeNode root, List list) {
            if(root == null) {
                return;
            }
            dfs(root.left, list);
            list.add(root.val);
            dfs(root.right, list);
        }
    
    }
     

    缺点:

    效率低下

    2.用迭代模拟递归
    class Solution {
        public List<Integer> inorderTraversal(TreeNode root) {
                List<Integer> result = new ArrayList();
                Stack<TreeNode> stack = new Stack();
                while(stack.size() > 0 || root != null) {
                    if(root != null) {
                        stack.add(root);
                        root = root.left;
                    } else {
                        root = stack.pop();
                        result.add(root.val);
                        root = root.right;
                    }
                }
                return result;
        }
    
    }
    

      

    缺点:

    效率低下
    3.莫里斯遍历
    用递归和迭代的方式都使用了辅助的空间,而莫里斯遍历的优点是没有使用任何辅助空间。
    缺点是改变了整个树的结构,强行把一棵二叉树改成一段链表结构。

    class Solution {
        public List<Integer> inorderTraversal(TreeNode root) {
            List<Integer> res = new ArrayList<Integer>();
            TreeNode pre = null;
            while(root!=null) {
                //如果左节点不为空,就将当前节点连带右子树全部挂到
                //左节点的最右子树下面
                if(root.left!=null) {
                    pre = root.left;
                    while(pre.right!=null) {
                        pre = pre.right;
                    }
                    pre.right = root;
                    //将root指向root的left
                    TreeNode tmp = root;
                    root = root.left;
                    tmp.left = null;
                //左子树为空,则打印这个节点,并向右边遍历    
                } else {
                    res.add(root.val);
                    root = root.right;
                }
            }
            return res;
        }
    }

    进阶

     颜色标记法

    其核心思想如下:

    使用颜色标记节点的状态,新节点为白色,已访问的节点为灰色。
    如果遇到的节点为白色,则将其标记为灰色,然后将其右子节点、自身、左子节点依次入栈。
    如果遇到的节点为灰色,则将节点的值输出。

    class Solution {
    
        class ColorNode {
            TreeNode treeNode;
            String color;
            public ColorNode(String color, TreeNode treeNode) {
                this.treeNode = treeNode;
                this.color = color;
            }
        }
    
        public List<Integer> inorderTraversal(TreeNode root) {
                List<Integer> result = new ArrayList();
                if(root == null) {
                    return result;
                }
                Stack<ColorNode> stack = new Stack();
                stack.push(new ColorNode("white", root));
                while(stack.size() > 0) {
                    ColorNode colorNode = stack.pop();
                    if("white".equals(colorNode.color)) {
                        if(colorNode.treeNode.right != null) {
                            stack.add(new ColorNode("white", colorNode.treeNode.right));
                        }
                        stack.add(new ColorNode("grey", colorNode.treeNode));
                        if(colorNode.treeNode.left != null) { 
                            stack.add(new ColorNode("white", colorNode.treeNode.left));
                        }
                    } else {
                        result.add(colorNode.treeNode.val);
                    }
                }
                return result;
        }
    

      如要实现前序、后序遍历,只需要调整左右子节点的入栈顺序即可。



  • 相关阅读:
    [Tips] uncompyle6进行python的pyc反编译
    [Tips] pip太慢,换源
    [Notes] docker build与docker file
    [Tips] 生成当前python环境的依赖
    [Tips] imagePullPolicy取值
    [Tips] docker镜像和容器导出导入
    js模块化历程
    从一个简单例子来理解js引用类型指针的工作方式
    数组去重的方法总结
    js中const,var,let区别
  • 原文地址:https://www.cnblogs.com/s648667069/p/13681229.html
Copyright © 2011-2022 走看看