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;
    }

 

posted @ 2018-10-12 11:15  skillking2  阅读(114)  评论(0编辑  收藏  举报