二叉树——二叉树的遍历(递归与迭代)
二叉树的遍历中,递归版本都是利用系统提供的栈,自动将当前结点的各种信息压栈
而在迭代版本中,要自己手动的进行压栈,所以都需要一个栈
递归版本中,都经过结点三次
迭代版本中,都经过结点两次
先序遍历
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);
}
}
}
}

浙公网安备 33010602011771号