迭代遍历本质就是递归,不利用函数自调用,那么就选用stack进行递归。
前序遍历
遍历顺序为根左右,但是要注意,遍历顺序和压栈顺序是反的,所以输出根信息后要先入栈右节点,在入栈左节点。
上代码:
//20遍历二叉树
public class BinaryTree20 {
public static void main(String[] args) {
TreeNode node7 = new TreeNode(7,null,null);
TreeNode node6 = new TreeNode(6,null,null);
TreeNode node5 = new TreeNode(5,node6,node7);
TreeNode node4 = new TreeNode(4,null,null);
TreeNode node3 = new TreeNode(3,null,null);
TreeNode node2 = new TreeNode(2,node4,node5);
TreeNode node1 = new TreeNode(1,node2,node3);
preOrder(node1);
}
//前序遍历利用栈结构
public static void preOrder(TreeNode head) {
if (head != null) {
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.add(head);
while (!stack.isEmpty()) {
head = stack.pop();
if(head != null){
System.out.println(head.val);
stack.push(head.right);
stack.push(head.left);
}
}
}
}
}
结果:1245673
中序遍历
中序遍历顺序为左根右,所以应当不断入栈左子节点,直到遇到空,就出栈该节点,打印他的数值。这一步之后,栈顶保留的就是左子节点的父节点了,这个时候令root=root.right,假如没有右节点,那么就可以遍历根节点了。保证左根右的顺序。
上代码:
import java.util.Stack;
//20遍历二叉树
public class BinaryTree20 {
public static void main(String[] args) {
TreeNode node7 = new TreeNode(7,null,null);
TreeNode node6 = new TreeNode(6,null,null);
TreeNode node5 = new TreeNode(5,node6,node7);
TreeNode node4 = new TreeNode(4,null,null);
TreeNode node3 = new TreeNode(3,null,null);
TreeNode node2 = new TreeNode(2,node4,node5);
TreeNode node1 = new TreeNode(1,node2,node3);
midOrder(node1);
}
//中序:将左子节点入栈,出栈打印值,然后添加右子节点
public static void midOrder(TreeNode root) {
if (root!=null){
Stack<TreeNode> stack = new Stack<>();
while (!stack.isEmpty()||root != null){
if (root!=null){
stack.push(root);
root = root.left;
}else {
root = stack.pop();
System.out.println(root.val);
root = root.right;
}
}
}
}
}
结果:4265713
后序遍历
后序遍历顺序是左右根,首选寻找最左边的子节点。如果他的右节点为空或者被遍历过了,那么这个最左边的子节点就是根节点,输出他。如果右节点存在且没有被打印过,那么此时还不能打印这个左节点,得重新入栈,然后查找右节点。
上代码:
import java.util.Stack;
//20遍历二叉树
public class BinaryTree20 {
public static void main(String[] args) {
TreeNode node7 = new TreeNode(7,null,null);
TreeNode node6 = new TreeNode(6,null,null);
TreeNode node5 = new TreeNode(5,node6,node7);
TreeNode node4 = new TreeNode(4,null,null);
TreeNode node3 = new TreeNode(3,null,null);
TreeNode node2 = new TreeNode(2,node4,node5);
TreeNode node1 = new TreeNode(1,node2,node3);
// preOrder(node1);
// midOrder(node1);
lastOrder(node1);
}
//后序:
public static void lastOrder(TreeNode root) {
if (root != null) {
Stack<TreeNode> stack = new Stack<>();
TreeNode prev = null;
while (root != null || !stack.isEmpty()) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();//root的左子节点为null
if (root.right == null || root.right == prev) {//右子节点为null,或者右子节点已打印
System.out.println(root.val);
prev = root;
root = null;
} else {//右子节点有值,重新入栈
stack.push(root);
root = root.right;
}
}
}
}
}
结果:4675231
层序遍历
从上到下,从左到右。每次遍历到一个节点,入栈,同时左右子节点入队列FIFO。
上代码:
//20遍历二叉树
public class BinaryTree20 {
public static void main(String[] args) {
TreeNode node7 = new TreeNode(7, null, null);
TreeNode node6 = new TreeNode(6, null, null);
TreeNode node5 = new TreeNode(5, node6, node7);
TreeNode node4 = new TreeNode(4, null, null);
TreeNode node3 = new TreeNode(3, null, null);
TreeNode node2 = new TreeNode(2, node4, node5);
TreeNode node1 = new TreeNode(1, node2, node3);
levelOrder(node1);
}
// 层序遍历
public static void levelOrder(TreeNode root) {
Queue<TreeNode> q = new LinkedList<>();
q.add(root);
while (!q.isEmpty()){
TreeNode node = q.poll();
if (node != null) {
System.out.println(node.val);
q.add(node.left);
q.add(node.right);
}
}
}
}
结果:1234567