二叉树遍历的非递归Java实现

    关于二叉树的3种遍历方式原理,原文博主已经详细介绍了,这里只附上非递归形式的Java代码。

    原文地址:http://blog.csdn.net/pi9nc/article/details/13008511/

    关于二叉树,请参考另一篇文章:http://blog.csdn.net/ifleetingtime/article/details/78836638

/**
 * 非递归,遍历整个树
 * 中序遍历
 * 顺序: 左子节点 -> 父节点 -> 右子节点
 */
public void in_traverse() {
	if (root == null)
		return ;
	
	Stack<Node> stack = new Stack<>(); // 暂存节点
	Node currentNode = root;
	
	while (true) {
		
		if (currentNode.getLeftNode() != null) {
			stack.push(currentNode);   	// 将当前节点 A 入栈
			
			currentNode = currentNode.getLeftNode(); // 如果当前节点有左子节点,继续执行左子节点
		}
		else {
			System.out.print(currentNode.getData() + " ");
			
			currentNode = currentNode.getRightNode(); // 将此节点A 从栈中拿出来,获取它的右子节点
			while (currentNode==null && !stack.isEmpty()) {
				currentNode = stack.pop(); // A的右子节点为空,继续出栈,找父节点
				System.out.print(currentNode.getData() + " "); // 找到父节点之后,先打印父节点,再去找其右节点
				currentNode = currentNode.getRightNode();
			}
			if (currentNode == null)    // 如果栈空了,没有找到右子节点,则循环完成
				break;                  
			// else  continue        // 否则 将右子节点作为当前节点继续遍历
		}
	}
}


/**
 * 非递归,遍历整个树
 * 前序遍历
 * 顺序: 父节点 -> 左子节点 -> 右子节点
 */
public void pre_traverse() {
	if (root == null)
		return ;
	
	Stack<Node> stack = new Stack<>(); // 暂存节点
	Node currentNode = root;
	
	while (true) {
		System.out.print(currentNode.getData() + " ");
		stack.push(currentNode);   	// 将当前节点 A 入栈
		
		if (currentNode.getLeftNode() != null) {
			currentNode = currentNode.getLeftNode(); // 如果当前节点有左子节点,继续执行左子节点
		}
		else {
			currentNode = stack.pop().getRightNode(); // 将此节点A 从栈中拿出来,上面刚放进去,获取它的右子节点
			while (currentNode==null && !stack.isEmpty()) {
				currentNode = stack.pop().getRightNode(); // A的右子节点为空,继续出栈,找父节点的右子节点, 找到第一个存在的右子节点
			}
			if (currentNode == null)    // 如果栈空了,没有找到右子节点,则循环完成
				break;                  
			// else  continue        // 否则 将右子节点作为当前节点继续遍历
		}
	}
}


/**
 * 非递归,遍历整个树
 * 后序遍历
 * 顺序: 左子节点 -> 右子节点  -> 父节点
 */
public void post_traverse() {
	if (root == null)
		return ;
	
	Stack<Node> stack = new Stack<>(); // 暂存节点
	Node currentNode = root;
	Node lastNode = null;  // 暂存上一个数据的节点
	
	stack.push(currentNode); // 先将根节点入栈
	
	while (!stack.isEmpty()) {
		
		currentNode = stack.peek(); // 获取栈顶元素,不要移除它,不移除的原因: 子节点可能没遍历到,要把子节点压在这个节点上面,先执行子节点
		
		// 如果此时的元素没有左右节点,或者左右节点已经被遍历过了,因为是自下向上遍历,子节点永远是父节点之前紧挨着遍历到的,所以我们用一个lastNode变量保存上一个遍历到的节点
		if ( (currentNode.getLeftNode()==null && currentNode.getRightNode()==null) ||
			 ( lastNode!=null && (currentNode.getLeftNode()==lastNode || currentNode.getRightNode()==lastNode) )	
		   )
		{
			System.out.print(currentNode.getData() + " ");
			lastNode = currentNode;
			stack.pop(); // 这个节点自身,和子节点都遍历到了,移除,从父节点开始重新遍历
		}
		else {
			// 先入栈右子节点,再入栈左子节点, 这样从栈中取数据时,先执行左子节点,再执行右子节点
			if (currentNode.getRightNode() != null) {
				stack.push(currentNode.getRightNode());
			}
			if (currentNode.getLeftNode() != null) {
				stack.push(currentNode.getLeftNode());
			}
		}
		
	}
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值