二叉树的遍历打印,递归与非递归详解

二叉树的遍历打印,递归与非递归

首先小编介绍一下三种遍历(先序,中序,后序)。这里我给大家总结了一个万能公式。因为我看了很多人讲这几种遍历序列,但是我觉得都很一般,所有我给大家总结一下。保证你听了之后再也不出错,而且不需要死记什么左中右,左右中。。。。这种东西。
方法:我们拿这笔去走一边这一颗树,按照从头结点访问左节点到最左,然后最左结点访问有无右节点。也可以说是按先序方式访问整颗树,关键来了。走的过程中有一次经过的结点序列叫先序遍历,两次经过的结点叫中序遍历,三次经过的结点叫后序! 这样再也不用记什么三种序列的先后顺序了。因为每个结点走的过程都会经历三次。

这次的代码有点多,耐下心来听我说。
代码的重要步骤我都有详细注释。并且解释看非递归用栈怎么操作。把这些操作理解,然后看代码。会理解的更流畅。


//二叉树的遍历 递归和非递归
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(); 
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值