leetcode(144):Binary Tree Preorder Traversal

题目

Binary Tree Preorder Traversal
Given a binary tree, return the preorder traversal of its nodes’ values.

For example:
Given binary tree {1,#,2,3},
1
\
2
/
3
return [1,2,3].

思路

二叉树的前序遍历,递归和非递归两种。

注意,在Java中,List只是一个interface,不能直接进行实例化,所以如果要创建List对象,通过声明ArrayList、LinkedList、Vector等对象来实现,这些类实现了List的interface。

此外,注意Integer和int的区别,可以参考文章《Integer与int的种种比较你知道多少?》。简单总结如下:

  • Ingeter是int的包装类,是引用类型,int为基本类型。
  • 当需要往ArrayList,HashMap中放东西时,像int,double这种内建类型是放不进去的,因为容器都是装object的,这是就需要这些内建类型的外覆类了。Java中每种内建类型都有相应的外覆类。
  • 无论如何,Integer与new Integer不会相等。
  • java在编译Integer i2 = 128的时候,被翻译成-> Integer i2 = Integer.valueOf(128);而valueOf()函数会对-128到127之间的数进行缓存。比如,Integer i5 = 127时,会将127进行缓存,下次再写Integer i6 = 127时,就会直接从缓存中取,就不会new了。
  • new Integer的引用指向堆,而位于-128~127之间的Integer则指向专门存放他的内存(常量池),他们的内存地址不一样
  • 两个都是非new出来的Integer比较,如果数在-128到127之间,则是true,否则为false;
  • 两个都是new出来的比较,都为false
  • int和integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比
  • jdk1.5之后,能够对int自动装包,对Integer自动拆包,完成这两者之间的转换

递归解法

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if (root != null) {
            list.add(Integer.valueOf(root.val));
            List<Integer> listLeft = preorderTraversal(root.left);
            list.addAll(listLeft);
            List<Integer> listRight = preorderTraversal(root.right);
            list.addAll(listRight);
            return list;
        }
        return list;
    }
}

方法一

  1. Create an empty stack, Push root node to the stack.
  2. Do following while stack is not empty.
    2.1. pop an item from the stack and print it.
    2.2. push the right child of popped item to stack.
    2.3. push the left child of popped item to stack.
public List<Integer> preorderTraversal(TreeNode root) {
    List<Integer> result = new LinkedList<>();
    Deque<TreeNode> stack = new LinkedList<>();
    stack.push(root);
    while (!stack.isEmpty()) {
        TreeNode node = stack.pop();
        if (node != null) {
            result.add(node.val);
            stack.push(node.right);
            stack.push(node.left);
        }
    }
    return result;
}

方法二

只保存右孩子

public List<Integer> preorderTraversal(TreeNode node) {
    List<Integer> list = new LinkedList<Integer>();
    Stack<TreeNode> rights = new Stack<TreeNode>();
    while(node != null) {
        list.add(node.val);
        if (node.right != null) {
            rights.push(node.right);
        }
        node = node.left;
        if (node == null && !rights.isEmpty()) {
            node = rights.pop();
        }
    }
    return list;
}

方法三

根据前序遍历访问的顺序,优先访问根结点,然后再分别访问左孩子和右孩子。即对于任一结点,其可看做是根结点,因此可以直接访问,访问完之后,若其左孩子不为空,按相同规则访问它的左子树;当访问其左子树对于任一结点P:

  1. 访问结点P,并将结点P入栈;
  2. 判断结点P的左孩子是否为空:
    2.1. 若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1;
    2.2. 若不为空,则将P的左孩子置为当前的结点P;
  3. 直到P为NULL并且栈为空,则遍历结束。
void preOrder2(BinTree *root)     //非递归前序遍历 
{
    stack<BinTree*> s;
    BinTree *p=root;
    while(p!=NULL||!s.empty())
    {
        while(p!=NULL)
        {
            cout<<p->data<<" ";
            s.push(p);
            p=p->lchild;
        }
        if(!s.empty())
        {
            p=s.top();
            s.pop();
            p=p->rchild;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值