leetcode--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].

分类:二叉树

题意:前序遍历二叉树


解法1:递归

/**
 * 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> res = new ArrayList<Integer>();
		if(root!=null) helper(res,root);
		return res;
    }
	
	public void helper(List<Integer> res,TreeNode n){
		res.add(n.val);
		if(n.left!=null) helper(res, n.left);
		if(n.right!=null) helper(res, n.right);
	}
}


解法2:使用栈模拟递归

/**
 * 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> res = new ArrayList<Integer>();
		if(root==null) return res;
		Stack<TreeNode> stack = new Stack<TreeNode>();
		stack.add(root);
		while(!stack.isEmpty()){
		    TreeNode cur = stack.pop();
		    res.add(cur.val);
		    if(cur.right!=null) stack.add(cur.right);//右节点先进栈,从而后出栈
		    if(cur.left!=null) stack.add(cur.left);//左节点先进栈,从而先出栈
		}
		return res;
    }
}

解法3:morris二叉树遍历,空间O(1),时间O(n)

遍历过程如下:对于某个节点root,判断其是否有左子树,没有,则访问该节点,将当前节点设置为其右节点,重复上述过程。

有左子树,遍历获得左子树最右边的节点(也就是前序遍历中,左子树最后一个访问的节点),

如果这个节点的right为空,将这个节点的right设置为当前节点root,访问root,将当前节点设置为root的左节点

如果该节点right已经有指向,说明这个节点已经被线索化了,将当前节点设置为root的右节点,设置right为null清除线索

/**
 * 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> res = new ArrayList<Integer>();
		if(root==null) return res;
		TreeNode cur = root;
		TreeNode pre = null;
		while(cur!=null){//当前节点不为空,也就是没有到最后
		    if(cur.left==null){//如果当前节点左子树为空
		        res.add(cur.val);//访问当前节点
		        cur = cur.right;//设置其右节点为当前节点
		    }else{//如果左子树不为空
		        pre = cur.left;
		        while(pre.right!=null&&pre.right!=cur){//获得左子树最右边的节点
		            pre = pre.right;
		        }
		        if(pre.right==null){//如果最右边节点没有被线索化
		            pre.right = cur;//线索化
		            res.add(cur.val);//访问当前节点
		            cur = cur.left;//设置其左节点为当前节点
		        }else{//如果被线索化了,说明这次访问,是为了访问其线索节点
		            pre.right = null;//取消线索化
		            cur = cur.right;//线索节点
		        }
		    }
		}
		return res;
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值