题目描述
给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
1:递归
思路分析
代码展示
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res=new ArrayList<>();
preOrder( root,res);
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);//然后存进右节点
}
}
示例分析
如下图,程序的执行流程如红圈①到⑨
复杂度分析
2:迭代
解题思路
我们也可以用迭代的方式实现方法一的递归函数,两种方式是等价的,区别在于递归的时候隐式地维护了一个栈,而我们在迭代的时候需要显式地将这个栈模拟出来,其余的实现与细节都相同
代码展示
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();//用来存遍历到的节点
if(root==null)
{
return res ;
}
Stack<TreeNode>stack=new Stack<>();
stack.push(root);
while(!stack.empty())
{
TreeNode node=stack.pop();//每次弹出栈顶
res.add(node.val);
if(node.right!=null)
{
stack.push(node.right);//压入右节点,这样保证只有左子树遍历完才会弹出右节点
}
if(node.left!=null)
{
stack.push(node.left);//压入左节点
}
}
return res;
}
}
示例分析
执行过程
迭代法:牛客官方
代码展示
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer>res=new ArrayList<>();
Stack<TreeNode>stack=new Stack<>();
if(root==null)
{
return res;
}
stack.push(root);
res.add(root.val);
TreeNode node=root.left;
while(!stack.empty()||node!=null)//||node!=null是为了防止遍历不到右节点
{
while(node!=null)
{
res.add(node.val);
stack.push(node);
node=node.left;//有左节点就一直深度遍历完可以遍历的左节点
}
node=stack.pop();//弹出栈顶节点
node=node.right;//遍历弹出节点的右节点
}
return res;
}
}
示例分析
复杂度分析
3:Morris 遍历
解题思路
代码展示
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer>res=new ArrayList<>();
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;
}
}
复杂度分析
错误总结
解决:
return ; //........也不行,返回类型不匹配