二叉树的遍历打印,递归与非递归
首先小编介绍一下三种遍历(先序,中序,后序)。这里我给大家总结了一个万能公式。因为我看了很多人讲这几种遍历序列,但是我觉得都很一般,所有我给大家总结一下。保证你听了之后再也不出错,而且不需要死记什么左中右,左右中。。。。这种东西。
方法:我们拿这笔去走一边这一颗树,按照从头结点访问左节点到最左,然后最左结点访问有无右节点。也可以说是按先序方式访问整颗树,关键来了。走的过程中有一次经过的结点序列叫先序遍历,两次经过的结点叫中序遍历,三次经过的结点叫后序! 这样再也不用记什么三种序列的先后顺序了。因为每个结点走的过程都会经历三次。
这次的代码有点多,耐下心来听我说。
代码的重要步骤我都有详细注释。并且解释看非递归用栈怎么操作。把这些操作理解,然后看代码。会理解的更流畅。
//二叉树的遍历 递归和非递归
import java.util.Stack;
//结点定义
class TreeNode{
public int value;
public TreeNode leftChild;
public TreeNode rightChild;
public TreeNode(int data,TreeNode lc,TreeNode rc){
this.value = data;
this.leftChild = lc;
this.rightChild = rc;
}
}
public class TreeSearch {
public static void main(String[] args) {
TreeNode node6 = new TreeNode(6,null,null);
TreeNode node5 = new TreeNode(5,null,null);
TreeNode node4 = new TreeNode(4,null,null);
TreeNode node3 = new TreeNode(3,node5,node6);
TreeNode node2 = new TreeNode(2,node4,null);
TreeNode node1 = new TreeNode(1,node2,node3);
//采用递归方法
System.out.println("-------递归先序遍历-------");
pre(node1);System.out.println();
System.out.println("-------递归中序遍历-------");
in(node1);System.out.println();
System.out.println("-------递归后序序遍历-------");
pos(node1);System.out.println();
//非递归方法
System.out.println("-------非递归先序遍历-------");
preStack(node1);System.out.println();
System.out.println("-------非递归中序遍历-------");
inStack(node1);System.out.println();
System.out.println("-------递归后序序遍历-------");
posStack(node1);System.out.println();
}
//递归先序打印所有节点
public static void pre(TreeNode head){
if(head==null) return;
System.out.print(head.value+" ");
pre(head.leftChild);
pre(head.rightChild);
}
//递归中序打印所有节点
public static void in(TreeNode head){
if(head==null)return;
in(head.leftChild);
System.out.print(head.value+" ");
in(head.rightChild);
}
//递归后序打印所有节点
public static void pos(TreeNode head){
if(head==null) return;
pos(head.leftChild);
pos(head.rightChild);
System.out.print(head.value+" ");
}
//非递归用栈先序打印所有节点分为三部曲
/*
* 1.弹出栈时就打印
* 2.如果有右孩子就压入右
* 3.如果有左孩子再压入左
* */
public static void preStack(TreeNode head){
if(head==null) return;
if(head!=null){
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.add(head);
while(!stack.isEmpty()){
head=stack.pop();
System.out.print(head.value+" ");
if(head.rightChild!=null){
stack.push(head.rightChild);
}
if(head.leftChild!=null){
stack.push(head.leftChild);
}
}
}
//换行
//System.out.println();
}
//非递归用栈后序打印所有节点分为三部曲
/*
* 1.弹出一个是进入另一个栈
* 2.如有左,压入左
* 3.如有右,压入右
* */
public static void posStack(TreeNode head){
if(head==null) return;
if(head!=null){
Stack<TreeNode> s1 = new Stack<TreeNode>();
Stack<TreeNode> s2 = new Stack<TreeNode>();
s1.push(head);
while(!s1.isEmpty()){
head=s1.pop();
s2.push(head);
if(head.leftChild!=null){
s1.push(head.leftChild);
}
if(head.rightChild!=null){
s1.push(head.rightChild);
}
}
while(!s2.isEmpty()){
System.out.print(s2.pop().value+" ");
}
//换行
// System.out.println();
}
}
//非递归用栈中序打印所有节点分为二步曲
/*
* 1.整条左边界依次进入栈
* 2.如果1无法继续时,弹出节点就打印,来到右数上继续执行1
* */
public static void inStack(TreeNode head){
if(head!=null){
Stack<TreeNode> stack = new Stack<TreeNode>();
while(!stack.isEmpty() || head!=null){
if(head!=null){
stack.push(head);
head=head.leftChild;
}
else {
head=stack.pop();
System.out.print(head.value+" ");
head=head.rightChild;
}
}
}
//换行
// System.out.println();
}
}