难度:简单
今天刷二叉树的前序遍历,大家有兴趣可以点上看看题目要求,试着做一下。
给你二叉树的根节点?root
?,返回它节点值的?前序?遍历。
方法1、递归
方法2、迭代
方法3、Morris遍历
首先,按照二叉树前序遍历访问规律可知,即根节点——左子树——右子树,在访问左子树或者右子树的时候,我们按照同样的方式遍历,直到遍历完整棵树。
因此整个遍历过程天然具有递归的性质,我们可以直接用递归函数来模拟这一过程
定义preorder(root)表示当前遍历到root节点的答案。
将root节点的值添加到list中
递归调用遍历左子树,接着遍历右子树
直到遇到空节点,递归结束
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();//创建集合存储遍历节点值
preorder(root, res);//调用preorder()方法
return res;
}
public void preorder(TreeNode root, List<Integer> res) {
if (root == null) { //终止条件为树为空时
return;
}
res.add(root.val); //添加遍历所得的节点值
preorder(root.left, res); //遍历左子树
preorder(root.right, res);//遍历右子树
}
}
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if (root == null) {
return res;
}
Deque<TreeNode> stack = new LinkedList<TreeNode>();
TreeNode node = root;
while (!stack.isEmpty() || node != null) {
while (node != null) {
res.add(node.val);
stack.push(node);
node = node.left;
}
node = stack.pop();
node = node.right;
}
return res;
}
}
这里主要是用迭代的方式实现方法1中的递归函数部分,两种方式等价的,区别在于
递归是隐式维护一个栈,而迭代则是显式将这个栈模拟出来
其余实现均相同,具体参考上面的代码?
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
if (root == null) {
return res;
}
TreeNode p1 = root, p2 = null;
while (p1 != null) {
p2 = p1.left;
if (p2 != null) {
while (p2.right != null && p2.right != p1) {
p2 = p2.right;
}
if (p2.right == null) {
res.add(p1.val);
p2.right = p1;
p1 = p1.left;
continue;
} else {
p2.right = null;
}
} else {
res.add(p1.val);
}
p1 = p1.right;
}
return res;
}
}