zoukankan      html  css  js  c++  java
  • 144. Binary Tree Preorder Traversal

    一、题目

      1、审题

      

      2、分析

        给出一棵二叉树,采用迭代输出先序遍历的节点值。

    二、解答

      1、思路:

        方法一、

          采用 Stack + 迭代的方式。

        public List<Integer> preorderTraversal(TreeNode root) {
            
            List<Integer> result = new ArrayList<>();
            if(root == null)
                return result;
            
            Stack<TreeNode> stack = new Stack<>();
            stack.add(root);
            
            while(!stack.isEmpty()) {
                
                TreeNode node = stack.pop();
                result.add(node.val);
                
                if(node.right != null)
                    stack.add(node.right);
                if(node.left != null)
                    stack.add(node.left);
            }
            
            return result;
        }

      优化: Stack 只用于存储 Right 节点。

    public List<Integer> preorderTraversal(TreeNode root) {
            List<Integer> result = new ArrayList<>();
            if(root == null)
                return result;
            // 只存储右节点
            Stack<TreeNode> rightStack = new Stack<>();
            TreeNode node = root;
            
            while(node != null) {
                result.add(node.val);
                if(node.right != null)
                    rightStack.add(node.right);
                
                node = node.left;
                if(node == null && !rightStack.isEmpty())
                    node = rightStack.pop();
            }
            return result;
        }

        方法二、

          采用 InOrder 方式遍历,但输出为 InOrder 顺序。

      public List<Integer> preorderTraversal(TreeNode root) {
            List<Integer> result = new ArrayList<>();
            if(root == null)
                return result;
            Stack<TreeNode> stack = new Stack<>();
            TreeNode node = root;
            while(node != null || !stack.isEmpty()) {
                while(node != null) {
                    stack.push(node);
                    result.add(node.val);
                    node = node.left;
                }
                
                node = stack.pop();
                node = node.right;
            }
            return result;
        }

      方法三、

        采用 Morris Traversal 方法线索二叉树,无需 Stack。

        public List<Integer> preorderTraversal4(TreeNode root) {
            
            TreeNode cur = root;
            TreeNode pre = null;
            List<Integer> list = new ArrayList<>();
            
            while(cur != null) {
                
                if(cur.left == null) {
                    list.add(cur.val);
                    cur = cur.right;
                }
                else {
                    pre = cur.left;
                    
                    // 找到中序遍历时  cur 的前一个节点
                    while(pre.right != null && pre.right != cur) 
                        pre = pre.right;
                    
                    // 说明 cur 的左子树没访问过
                    if(pre.right == null) { // 添加索引
                        list.add(cur.val);
                        pre.right = cur;
                        cur = cur.left;
                    }
                    else {    // cur 的前一个节点都访问过了,则删除索引
                        pre.right = null;
                        cur = cur.right;
                    }
                }
            }
            return list;
        }
  • 相关阅读:
    解读Unity中的CG编写Shader系列十 (光滑的镜面反射(冯氏着色))
    解读Unity中的CG编写Shader系列八(多光源漫反射)
    Unity3d《Shader篇》漫反射
    解读Unity中的CG编写Shader系列八(镜面反射)
    渲染物体到一张UITexture上
    解读Unity中的CG编写Shader系列六(漫反射)
    解读Unity中的CG编写Shader系列五(理论知识)
    解读Unity中的CG编写Shader系列四(unity中的圆角矩形shader)
    解读Unity中的CG编写Shader系列三
    解读Unity中的CG编写Shader系列二
  • 原文地址:https://www.cnblogs.com/skillking/p/9777035.html
Copyright © 2011-2022 走看看