首页 > 其他 > 详细

[lintcode] Binary Tree Preorder Traversal

时间:2015-10-06 11:28:25      阅读:160      评论:0      收藏:0      [点我收藏+]

Binary Tree Preorder Traversal

Given a binary tree, return the preorder traversal of its nodes‘ values.

Example

Given binary tree {1,#,2,3}:

1
   2
 /
3

return [1,2,3].

 

SOLUTION 1:

这题首先应该想到递归做法,最简单直观的也是递归做法。首先先来说一下递归是什么,递归其实就是自己调用自己,但是注意的是,递归往往没有返回值。

在用递归方法的时候要定义清楚,递归方法接收了什么参数,做了什么事情,在这个题里面,看到返回值是个ArrayList,那么首先应该new一个存放结果的ArrayList并且用于最后返回,

所以说递归函数一定会接受一个ArrayList,而且一定会有一个根结点,所以这个递归函数应该是这样的:traversal(TreeNode root, ArrayList<Integer> result){},然后定义这个函数做了什么事情,就是把以root为根的前序遍历加到result里面。

时间复杂度就是O(h) [h是二叉树高度,换算一下就是,设n为点个数,h = log n]

也就是O(log n)

后面就很简单的看一下代码了:

public class Solution {
    /**
     * @param root: The root of binary tree.
     * @return: Preorder in ArrayList which contains node values.
     */
    public ArrayList<Integer> preorderTraversal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList<Integer>();
        if (root == null){
            return result;
        }
        traversal(root, result);
        return result;
    }
    private void traversal(TreeNode root, ArrayList<Integer> result){
        if (root == null){
            return;
        }
        result.add(root.val);
        traversal(root.left, result);
        traversal(root.right, result);
    }
}

  

SOLUTION 2:

第二种方法,就是几乎使用所有二叉树的分治法,分治法其实也是一种递归方法,不过相当于把给的参数分成两部分,分别处理,在二叉树这种结构中,天然的把自己分成了两个部分,可以直接使用分治法。

注意的是分治法一般都是有返回值的,这个跟一般的递归方法是不一样的。

再注意的是,在极端情况下(二叉树退化成链表)这时时间复杂度会从O(log n)退化成O(n) [n 是点个数]

代码如下:

public class Solution {
    /**
     * @param root: The root of binary tree.
     * @return: Preorder in ArrayList which contains node values.
     */
    public ArrayList<Integer> preorderTraversal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList<Integer>();
        if (root == null){
            return result;
        }
        // 左右两边分别递归处理===》分治法之“分”
        ArrayList<Integer> left = preorderTraversal(root.left);
        ArrayList<Integer> right = preorderTraversal(root.right);
        // 左右两边再跟根结点合并
        result.add(root.val);
        result.addAll(left);
        result.addAll(right);
        return result;
    }
}

SOLUTION 3:

比较重要的是第三种方法,这种方法是非递归方法。

对于递归方法,它的一个坏处就是会stack overflow,就是栈溢出,这个是由于当运行一个程序的时候,系统会自动分配给这个程序一块栈内存,8MB,也就是说,递归过深的时候,就会消耗大量栈空间,当其超过8MB时候就会栈溢出,所以,往往能用非递归就不用递归,除非非递归太复杂了。

非递归的解体方法就是用栈(stack)模拟递归。具体方法见代码:

public class Solution {
    /**
     * @param root: The root of binary tree.
     * @return: Preorder in ArrayList which contains node values.
     */
    public ArrayList<Integer> preorderTraversal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList<Integer>();
        if (root == null){
            return result;
        }
        Stack<TreeNode> stack = new Stack<TreeNode>();
        stack.push(root);
        while (!stack.empty()){
            TreeNode temp = stack.pop();
            result.add(temp.val);
            // 由于stack是先进后出,所以压栈时候要先压入right子树
            // 这样才能保证出栈时候是左先出,右后出
            if (temp.right != null){
                stack.push(temp.right);
            }
            if (temp.left != null){
                stack.push(temp.left);
            }
        }
        return result;
    }
}

  

 

[lintcode] Binary Tree Preorder Traversal

原文:http://www.cnblogs.com/tritritri/p/4856833.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!