二叉树的遍历中,递归版本都是利用系统提供的栈,自动将当前结点的各种信息压栈
而在迭代版本中,要自己手动的进行压栈,所以都需要一个栈
递归版本中,都经过结点三次
迭代版本中,都经过结点两次
先序遍历
public class PreOrderRecursive { public static void preOrderRecursive(Tree tree){ if(tree == null) return; System.out.print(tree.val + " "); preOrderRecursive( tree.left ); preOrderRecursive( tree.right ); } }
迭代版本:采用一个stack栈,来存放结点,有右先压右,有左后压左
利用栈的特性,从根部开始,依次入栈,然后依次出栈,出栈的同时,
要把它的右 左孩子(注意顺序,如果存在的话)加到栈中,直到栈中没有元素为止
public class PreOrderNonRecursive { public static void preOrderNonRecursive(Tree tree){ if(tree == null) return; Stack<Tree> stack = new Stack<>(); stack.push(tree); while(!stack.empty()){ Tree subTree = stack.pop(); System.out.print(subTree.val + " "); if(subTree.right != null){ stack.push(subTree.right); } if(subTree.left != null){ stack.push(subTree.left); } } } }
中序遍历
public class InOrderRecursive { public static void inOrderRecursive(Tree tree){ if(tree == null) return; inOrderRecursive(tree.left); System.out.print(tree.val + " "); inOrderRecursive(tree.right); } }
迭代版本:
当前节点不为空,当前节点入栈,当前节点向左走
只有当前节点为空时,才弹出一个节点(出栈),打印,然后当前节点向右走
public class InOrderNonRecursive { public static void inOrderNonRecursive(Tree tree){ if(tree == null) return; Stack<Tree> stack = new Stack<>(); while(!stack.empty() || tree != null){ //若当前结点不为空,把当前节点左子树的一排都压进来,(当前结点入栈,并且当前结点向左走) if(tree != null){ stack.push(tree); tree = tree.left; } else{ //若当前结点为空,则将栈中的一个结点弹出,并打印,然后当前结点向右走 tree = stack.pop(); System.out.print(tree.val + " "); tree = tree.right; } } } }
后序遍历
public class PostOrderRecursive { public static void postOrderRecursive(Tree tree){ if(tree == null) return; postOrderRecursive( tree.left ); postOrderRecursive( tree.right ); System.out.print(tree.val + " "); } }
迭代版本:
因为先序遍历的顺序是 中左右, 后序遍历的顺序是 左右中
采用先序遍历的变形,首先实现一个中右左的遍历,然后将其压入辅助栈中,最后依次将辅助栈中的元素弹出即可
public class PostOrderNonRecursive { public static void postOrderNonRecursive(Tree tree){ if(tree == null) return; Stack<Tree> stack = new Stack<>(); Stack<Tree> stackHelp = new Stack<>(); stack.push(tree); while(!stack.empty()){ Tree subTree = stack.pop(); stackHelp.push(subTree); if(subTree.left != null){ stack.push(subTree.left); } if(subTree.right != null){ stack.push(subTree.right); } } while(!stackHelp.empty()){ System.out.print(stackHelp.pop().val + " "); } } }
层序遍历
没有递归版本,只有迭代版本,借助于队列,先入先出
public class SequenceTranversal { public static void sequenceTranversal(Tree tree){ if(tree == null) return; Queue<Tree> queue = new LinkedList<>(); queue.offer(tree); while(!queue.isEmpty()){ Tree subTree = queue.poll(); System.out.print(subTree.val + " "); if(subTree.left != null){ queue.offer(subTree.left); } if(subTree.right != null){ queue.offer(subTree.right); } } } }