非递归实现二叉树遍历(思路+代码)

package 非递归遍历二叉树;

import java.util.*; //导入含有集合框架的包
public class Example { 
	static int SIZE=10;   //设定数组大小
	/*
	 * 构建createArray方法生成大小为SIZE的随机数组
	 * Math。random()方法返回带正号的 double 值,该值大于等于 0.0 且小于 1.0。
	 * 返回值是一个伪随机选择的数,在该范围内(近似)均匀分布。 
	 */
	public static int[] createArray(){
		int[] shuzu=new int[10];
		for(int i=0;i<SIZE;i++){
	         shuzu[i]=(int)(Math.random()*100);
		  }
		
		return shuzu;
	}
	
	public static int[] array=createArray();  //将createArray方法的返回值赋给数组变量array
    private static List<Node> nodeList=null;   //将List实例对象初始化为空
    /*
     * 构建Node类
     * 分别定义其左子节点leftChild,右子节点rightChild
     */

	private static class Node{
		Node leftChild;
		Node rightChild;
		int data;
		Node(int newData){
			leftChild=null;
			rightChild=null;
			data=newData;
			
		}
		
	}
	/*
	 * 构建完全二叉树
	 */
	public void createBinTree(){
		nodeList=new LinkedList<Node>();
		System.out.println("原数组是:");
	    for(int i=0;i<array.length;i++){
	    	System.out.print(array[i]+"  ");
	    }
	 
		for(int nodeIndex=0;nodeIndex<array.length;nodeIndex++){
			nodeList.add(new Node(array[nodeIndex]));
		}
		for(int parentIndex=0;parentIndex<array.length/2-1;parentIndex++){
			nodeList.get(parentIndex).leftChild=nodeList.get(parentIndex*2+1);
			nodeList.get(parentIndex).rightChild=nodeList.get(parentIndex*2+2);
		}
		int lastParentIndex=array.length/2-1;
		nodeList.get(lastParentIndex).leftChild=nodeList.get(lastParentIndex*2+1);
		
		if(array.length%2==1){
			nodeList.get(lastParentIndex).rightChild=nodeList.get(lastParentIndex*2+2);
		}
	}
	/*
	 * 采用非递归的方式遍历二叉树,主要是利用入栈出栈的方式,较递归方式来看,实现过程相对繁琐
	 */
	//前序遍历
	/*
	 * 思路:
	 * 1.申请一个栈,记为stack.然后将头节点head压入stack中
	 * 2.从stack中弹出栈顶节点,记为cur,然后打印cur节点的值,再将节点cur(不为空的话)先压入stack中,最后将cur的左孩子
	 *  (不为空的话)压入stack中
	 * 3.不断重复步骤2,直到stack为空为止,全部过程结束
	 */
	public static void preOrder(Node head){
		if(head!=null){
			Stack<Node> stack=new Stack();
			stack.add(head);
			while(!stack.empty()){
				head=stack.pop();
				System.out.print(head.data+"  ");
				if(head.rightChild!=null){
					stack.push(head.rightChild);
				}
				if(head.leftChild!=null){
					stack.push(head.leftChild);
				}
			}
			
		}
	}
	//中序遍历
	/*
	 * 思路:
	 * 1 申请一个新的栈,记为stack,初始时,令变量cur=head
	 * 2 先把cur节点压入栈中,对以cur节点为头的整棵子树来说,依次把左边界压入栈中,即不停地令cur=cur.left,然后重复步骤2
	 * 3 不断重复步骤2,直到cur为空,此时从stack中弹出一个节点,记为node。打印node的值,并且让cur=node.right,然后
	 * 继续重复步骤2
	 * 4 当stack为空且cur为空时,整个过程停止
	 */
	private static void inOrder(Node head) {
		if(head!=null){
			Stack<Node> stack=new Stack();
			while(!stack.isEmpty()||head!=null){
				if(head!=null){
					stack.push(head);
					head=head.leftChild;
				}
				else{
					head=stack.pop();
					System.out.print(head.data+"  ");
					head=head.rightChild;
				}
			}
		}

	}
	//后序遍历
	/*
	 * 思路:
	 * 1.申请两个栈,分别为s1,s2,然后将头节点head压入s1中
	 * 2.从s1中弹出出的节点记为cur,然后依次将cur的左孩子和右孩子压入s1中
	 * 3.在整个过程中,每一个从s1中弹出的节点都放进s2中
	 * 4.不断重复步骤2和步骤3,直到s1为空为止,过程停止
	 * 5.从s2中依次弹出节点并打印,打印的顺序就是后序遍历的顺序
	 */
	private static void postOrder(Node head) {
		if(head!=null){
			Stack<Node> s1=new Stack();
			Stack<Node> s2=new Stack();
			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().data+"  ");
			}
			
			
		}

	}
	public static void main(String[] args) {
		Example binTree=new Example();
		binTree.createBinTree();
		Node root=nodeList.get(0);
		System.out.println();
		System.out.println("先序遍历是"+"   ");
        preOrder(root);
        System.out.println();
        System.out.println("中序遍历是"+"   ");
        inOrder(root);
        System.out.println();
        System.out.println("后序遍历是"+"   ");
        postOrder(root);
        System.out.println();
	}

}


递归实现二叉树遍历的方法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值