二叉树的先序遍历、中序遍历以及后序遍历(递归以及非递归方式)

二叉树的遍历方式有两种:一种是比较简单的递归方式,另一种是借助栈实现的循环方式


1.先序遍历

a.先访问根节点

b.先序遍历左子树

c.先序遍历右子树

对应的递归算法:

public void preOrder(BNode root){
		if(root==null) return;
		else{
			System.out.print(root.data+" ");
			preOrder(root.left);
			preOrder(root.right);
		}
	}

由先序遍历过程可知,先访问根节点,再访问左子树,最后访问右子树,因此,先将根节点进栈,在栈不空时:出栈node,访问node节点,再将其右孩子节点进栈,再将左孩子节点进栈。

public void preOrder1(BNode root){
		Stack<BNode> st=new Stack<BNode>();
		BNode node=root;
		if(node!=null){
			st.push(node);     //根节点进栈
			while(st.size()>0){ // 栈不为空时进行循环
				node=st.pop();   //退栈并访问该节点
				System.out.print(node.data+" ");
				if(node.right!=null){  //有右孩子节点时,将右孩子压栈
					st.push(node.right);
				}
				if(node.left!=null){   //有左孩子节点时,将左孩子压栈
					st.push(node.left);
				}
			}
		}
	}

2.中序遍历

a.中序遍历左子树

b.访问根节点

c.中序遍历右子树

public void inOrder(BNode root){
		if(root==null) return;
		else{
			inOrder(root.left);
			System.out.print(root.data+" ");
			inOrder(root.right);
		}
	}

先扫描(并非访问)根节点的所有节点并一一将它们压栈。然后出栈一个节点node,访问node。然后扫描该节点的右孩子节点,将其进栈,再扫描右孩子节点的所有做节点并一一进栈,这样直到栈空为止。

public void inOrder1(BNode root){
		Stack<BNode> st=new Stack<BNode>();
		BNode node=root;
		while(node!=null || st.size()>0){
			while(node!=null) { //将根节点的左孩子都一一压栈
				st.push(node);
				node=node.left; 
			}
			if(st.size()>0){
				node=st.pop(); //出栈一个节点
				System.out.print(node.data+" ");
				node=node.right;
			}
		}
	}


3.后序遍历

a.后序遍历左子树

b.后序遍历右子树

c.访问根节点

public void postOrder(BNode root){
		if(root==null) return;
		else{
			postOrder(root.left);
			postOrder(root.right);
			System.out.print(root.data+" ");
		}
	}

先扫描根节点的所有左节点并一一进栈,出栈一个节点node,然后扫描该节点的右孩子节点并进栈,再扫描右孩子节点的所有左孩子节点并进栈。当一个节点的左、右孩子节点均被访问过后,再访问该节点,如此这样,直到栈空为止。为了判断当前节点node的右孩子节点已被访问过,用q保存刚访问过的节点,若node.right==q成立,说明node的左右孩子节点均被访问过,现在该访问node节点了。

public void postOrder1(BNode root){
		Stack<BNode> st=new Stack<BNode>();
		BNode node=root;
		BNode q;  //记录之前遍历的右节点
		int flag;
		if(node!=null){
		do{
			while(node!=null){  //将根节点的左孩子都一一压栈
				st.push(node);
				node=node.left;
			}
			q=null; //q指向栈顶节点的前一个已访问的节点
			flag=1; //flag=1表示处理栈顶节点
			while(st.size()>0 && flag==1){
				node=st.get(st.size()-1);
				//如果右节点为空或右节点之前遍历过
				if(node.right==null || node.right==q){
					System.out.print(node.data+" ");
					node=st.pop();
					q=node;
				}
				else{
					node=node.right;
					flag=0;  //flag=0表示栈顶节点处理完毕
				}
			}
		} while(st.size()>0);			
		}
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值