一、先搞懂原理
我们用前序递归作为例子:
这个递归大概应该都没问题!!那么我们怎么模拟系统栈呢?大餐来了,例如我们要遍历这个树
我们先要将1的根节点传入我们前序遍历的函数,这一步简称"go 1",进入后,我们就会把函数里的这三条命令压入系统栈,我们把输出简称为"print ";
取出栈顶,然后就输出1的值了,然后1的左节点进入函数就是"go 2",取栈顶,2进入函数,又是三个行,如下面:
然后输出2节点的值,继续去2的左节点,但是2没有左节点就直接返回了。什么都没做。然后一直弹出,直到1的右节点。
然后1的左节点进入函数,又是三个如图:
输出3的值,3的左右节点没有,栈为空,目前为止就打印出来完了。
我们进行了这些操作,始终离不开"go"、"print"这两个操作。因此我们把节点的操作和节点弄成一个类。
public static class Commond{
private String desc;
private TreeNode node;
public Commond(String desc, TreeNode node){
this.desc = desc;
this.node = node;
}
}
根据不同的行为,我们进行不同的操作!
二、非递归的前序
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res=new ArrayList<>();
Stack<Commond> stack=new Stack<>();
if(root != null) stack.push(new Commond("go", root));
else return res;
while(!stack.empty()){
Commond temp = stack.pop();
if(temp.desc.equals("go")){
if(temp.node.right != null)
stack.push(new Commond("go",temp.node.right));
if(temp.node.left != null )
stack.push(new Commond("go",temp.node.left));
stack.push(new Commond("print",temp.node));
}else{
res.add(temp.node.val);
}
}
return res;
}
public static class Commond{
private String desc;
private TreeNode node;
public Commond(String desc, TreeNode node){
this.desc = desc;
this.node = node;
}
}
}
三、非递归的中序
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res=new ArrayList<>();
Stack<Commond> stack=new Stack<>();
if(root != null) stack.push(new Commond("go", root));
else return res;
while(!stack.empty()){
Commond temp = stack.pop();
if(temp.desc.equals("go")){
if(temp.node.right != null)
stack.push(new Commond("go",temp.node.right));
stack.push(new Commond("print",temp.node));
if(temp.node.left != null )
stack.push(new Commond("go",temp.node.left));
}else{
res.add(temp.node.val);
}
}
return res;
}
public static class Commond{
private String desc;
private TreeNode node;
public Commond(String desc, TreeNode node){
this.desc = desc;
this.node = node;
}
}
}
四、非递归的后序
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res=new ArrayList<>();
Stack<Commond> stack=new Stack<>();
if(root != null) stack.push(new Commond("go", root));
else return res;
while(!stack.empty()){
Commond temp = stack.pop();
if(temp.desc.equals("go")){
stack.push(new Commond("print",temp.node));
if(temp.node.right != null)
stack.push(new Commond("go",temp.node.right));
if(temp.node.left != null )
stack.push(new Commond("go",temp.node.left));
}else{
res.add(temp.node.val);
}
}
return res;
}
public static class Commond{
private String desc;
private TreeNode node;
public Commond(String desc, TreeNode node){
this.desc = desc;
this.node = node;
}
}
}
五、总结
根据这三段代码,我们可以清晰看出我们只需要更换"go","print"的描述顺序,就可以实现前中后序的遍历了。是不是更简单了,更容易理解了。
最全面经及答案(已700+收藏量):
(5条消息) 2021年5月最新面经答案总结(Java基础、数据库、JVM、计网、计操、集合、多线程、Spring)_万小猿的博客-CSDN博客