中序遍历链接:
后序遍历链接:
题目地址:
难度:简单
今天刷二叉树的前序遍历,大家有兴趣可以点上看看题目要求,试着做一下。
题目:
给你二叉树的根节点 root
,返回它节点值的 前序 遍历。
我们直接看题解吧:
解题方法:
方法1、Morris遍历
方法2、递归
方法3、迭代
解题分析:
a. 前序遍历顺序:根节点->左子树->右子树(即根左右)
b. 递归方法虽易懂,但效率偏低;迭代方法,虽效率高,但不易理解
因此这里着重讲一下Morris方法。
解题思路:
1、新建临时节点,令该节点为 root;
2、如果当前节点的左子节点为空,则遍历当前节点的右子节点;
3、如果当前节点的左子节点不为空,则在当前节点的左子树上找最右的节点(左子树中序遍历的最后一个节点),即在中序遍历中的前驱节点;
· 如果前驱节点的右子节点为空,将前驱节点的右子节点设置为当前节点,当前节点更新为当前节点的左子节点。
·如果前驱节点的右子节点为当前节点,将它的右子节点重新设为空。倒序输出从当前节点的左子节点到该前驱节点这条路径上的所有节点。当前节点更新为当前节点的右子节点。
4、重复步骤 2 和步骤 3,直到遍历结束。
具体解题参考:144. 二叉树的前序遍历解题
代码实现:
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();//创建集合存储节点的值
if (root == null) {//对树的root节点进行判空,空则返回空集合
return res;
}
TreeNode p1 = root, p2 = null;//创建临时节点p1,p2,初始化p1=root
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;
}
}
代码实现(递归):
解题思路:
定义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中的递归函数部分,两种方式等价的,区别在于
递归是隐式维护一个栈,而迭代则是显式将这个栈模拟出来
其余实现均相同,具体参考上面的代码