- 使用
非递归
遍历二叉树
下列代码是绕二叉树一圈
去是,前序遍历,回是中序遍历
package com.luas.tree;
import java.util.LinkedList;
/**
* 使用while循环去走完一圈二叉树,使用栈来存储走过的路
*
* @author by FZB
* @date 2023/8/4
*/
public class TreeTraversal01 {
public static void main(String[] args) {
TreeNode root = new TreeNode(new TreeNode(new TreeNode(4), 2, null),
1,
new TreeNode(new TreeNode(5), 3, new TreeNode(6)));
//1.使用栈来记录走过的路,以便左节点遍历到头时可以返回
LinkedList<TreeNode> linkedList = new LinkedList<>();
//2.使用while循环先去走完左子树
TreeNode current = new TreeNode();
//3.首先将当前节点记录根节点的值
current = root;
//4.当当前节点不为null时表示左边还没有走到头,或者当栈不为空时,去原路回
while (current != null||!linkedList.isEmpty()) {
if (current != null) {
//5.每次将当前节点压入栈
linkedList.push(current);
System.out.println("去:" + current.val);
current = current.left;
} else {//6.当遍历到头时,出栈,原路返回,此时会发现,while循环根本进入不到else中的代码,所以需要加上||linkedList!=null
TreeNode pop = linkedList.pop();
System.out.println("回:"+pop.val);
//当栈中空了时就将根节点右节点的赋给当前节点,此时又会去执行if里面的语句且只将一个节点压入栈内,当走到头时,又会去赋值给右节点
current = pop.right;
}
}
}
}
非递归代码,去时打印是前序遍历,回时打印时中序遍历
- 使用非递归完成后序遍历
后序遍历时,需要判断什么时候才能出栈,因为后序遍历的顺序,是左右值,当右节点为null或者右节点处理完成时,才能进行弹出栈,那么什么时候右节点处理完成呢,就是当上一次弹出的元素为当前节点的右节点时,说明右节点处理完成,当前节点可以出栈
package com.luas.tree;
import java.util.LinkedList;
/**
* 二叉树的后序遍历
* 左右值
* @author by FZB
* @date 2023/8/8
*/
public class TreeTraversal02 {
public static void main(String[] args) {
TreeNode root = new TreeNode(new TreeNode(new TreeNode(4), 2, new TreeNode(7)),
1,
new TreeNode(new TreeNode(5), 3, new TreeNode(6)));
//使用栈来记录走过的路
LinkedList<TreeNode> stack = new LinkedList<>();
TreeNode current = root;
TreeNode pop = null;
while(current != null || !stack.isEmpty()){
if(current != null){
//去的时候,为了记录,将去的时候的路径放在栈里面
stack.push(current);
//System.out.println("去"+current.val);
current = current.left;
}else{
//当栈中不为空时,会来的时候从栈里面弹出来
//右子树处理完成才去弹出,一两种情况,一种是右子树为null
TreeNode peek = stack.peek();
//判断弹出节点的是是否是右节点,如果弹出的不是右节点说明右节点还没处理完成,此时还不能弹出
if(peek.right == null || peek.right == pop){
pop = stack.pop();
//将弹出右节点的赋给当前节点
System.err.println("回"+pop.val);
}else{
current = peek.right;
}
}
}
}
}
- 使用非递归完成前序中序后序遍历
package com.luas.tree;
import java.util.LinkedList;
/**
* 前序后序中序遍历通用模板
*
* 前序是 值 左 右
* 中序是 左 值 右
* 后序是 左 右 值
*
* @author by FZB
* @date 2023/8/8
*/
public class GlobalTraversal {
public static void main(String[] args) {
TreeNode root = new TreeNode(new TreeNode(new TreeNode(4), 2, new TreeNode(7)),
1,
new TreeNode(new TreeNode(5), 3, new TreeNode(6)));
//使用栈来记录走过的路
LinkedList<TreeNode> stack = new LinkedList<>();
TreeNode current = root;
TreeNode pop = null;
while (current != null || !stack.isEmpty()) {
if (current != null) {
stack.push(current);
System.out.println("前序遍历:"+ current.val);
current = current.left;
} else {
TreeNode peek = stack.peek();
// 没有右子树
if (peek.right == null) {
pop = stack.pop();
System.out.println("中序遍历:"+peek.val);
System.out.println("后序遍历:"+pop.val);
// 右子树处理完成
} else if (peek.right == pop) {
pop = stack.pop();
System.out.println("后序遍历:"+pop.val);
// 待处理右子树
} else {
System.out.println("中序遍历:"+peek.val);
current = peek.right;
}
}
}
}
}