【数据结构】-java实现二叉树的非递归遍历(先序、中序、后序)

为什么要选择非递归实现二叉树的遍历

递归实现二叉树的遍历具有代码简洁、易于理解的优点。但是缺点也不容小觑。最大的一个缺点就是效率低下
递归调用使用的是系统栈,所有的递归函数均调用系统栈。由此系统栈面向的递归函数也是不一样的。
非递归调用的是自己定义的栈,相对于系统栈有着术业有专攻的特点。
由于在的使用上不一样,当然,哪个比较适合选哪个栈了,由此非递归效率要高些。

非递归调用重要的是栈的入栈和出栈

每个人会有自己的树的结点类型定义,我的树的结点类型定义为BTNode ,参见结点创建

非递归先序遍历

重点注意哪个结点先进,哪个后进。

	public static void preOrder(BTNode btnode){
		 if(btnode==null)
			 System.out.println("是一个空树");
		 else{
			 BTNode[] stack=new BTNode[100] ;
			 int top=-1;
			 stack[++top]=btnode;//根节点入栈
			 while(top!=-1){
				 BTNode p=stack[top--];
				 System.out.print(p.getdata()+" ,");
				 //由于栈是先入后出的特性,注意哪个结点先进,那个后进
				 if(p.getrchild()!=null)
					 stack[++top]=p.getrchild();
				 if(p.getlchild()!=null)
					 stack[++top]=p.getlchild();				
			 }
		 }			 
	}
非递归中序遍历

中序遍历比较有意思:先将二叉树的的循环左结点入栈,为空时,出栈一个,然后访问右结点,随后接着遍历。

public static void inOrder(BTNode btnode){
		if(btnode==null)
			System.out.println("这是一个空树");
		else{
			BTNode[] stack=new BTNode[100];
			int top=-1;
			BTNode p=btnode;
			while(top!=-1||p!=null){//这里的||特别重要,因为会出现为-1的情况
				while(p!=null){
					stack[++top]=p;
					p=p.getlchild();
				}
				if(top!=-1){
					p=stack[top--];
					System.out.print(p.getdata()+" ,");
					p=p.getrchild();
				}
			}
		}
	}
非递归后序遍历

后序遍历的方式:左-右-根。逆后序的方式:根-右-左。由此,我们只需将先序遍历左右结点的顺序调换一下即可。即左结点先入栈,随后右结点入栈。
这里我们可以准备两个栈(A/B),A用来存储树型结点,B用来存储结点的数据。
将B中的所有出栈,即得后序遍历。

public static  int[] afterOrder(BTNode btnode){
		int[] outstack=new int[100];//B栈
		int n=-1;
		if(btnode==null)
			System.out.println("这是一个空树");
		else{
			
			BTNode[] stack=new BTNode[100] ;//A栈
			 int top=-1;
			 stack[++top]=btnode;
			while(top!=-1){
				BTNode p=stack[top--];
				outstack[++n]=p.getdata();
				//这是与非递归先序遍历相反的地方
				if(p.getlchild()!=null)
					stack[++top]=p.getlchild();
				if(p.getrchild()!=null)
					stack[++top]=p.getrchild();
			}
		}
		for(int i=n;i>0;i--)
			System.out.print(outstack[i]+" ,");
		return outstack;
	}
测试
public static void main(String[] args) {
		int[] array = { 0,1, 2, 3, 4, 5, 6, 7, 8,9,10,11,12};
		BuildTree demo = new BuildTree();
		demo.creatTree(array);
		System.out.print("二叉树的非递归先序排序为:");
		preOrder(BuildTree.list.get(0));
		System.out.println();
		System.out.print("二叉树的非递归中序排序为:");
		inOrder(BuildTree.list.get(0));
		System.out.println();
		System.out.print("二叉树的非递归后序排序为:");
		afterOrder(BuildTree.list.get(0));
		System.out.println();
		
 }
总结

非递归遍历让我们更加体会到这个数据结构的奥妙之处。
不管先序还是中序,重要的是理解先序、中序的原理,才能够在运用栈的时候得心应手。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值