二叉树前序Preorder遍历和后序Postorder遍历的非递归实现

1简述

二叉树的前序遍历和后序遍历的递归实现是相对容易实现的,而且非常便于理解。


对于前序遍历

       首先访问当前节点;

       如果左子树非空,前序遍历左子树;

       如果右子树非空,前序遍历右子树


对于后序遍历

       如果左子树非空,后序遍历左子树;

       如果右子树非空,后序遍历右子树;

       最后访问当前节点


2非递归实战

当采用非递归方法来说实现时,就要略微复杂一些了。

       首先来看前序遍历

       根据前序遍历的定义,我们总是访问当前节点,访问左子树,访问当前节点,访问左子树。。。只有当左子树为空时才会去访问右子树,接着就是重复这一过程;而当右子树为空的时候,我们要退回到上一个节点,查看上一个节点右子树是否为空,若非空,接着重复访问过程。因为有一个后退的过程,所以我们考虑用栈来保存访问经过的节点。在每次循环过程中,我们总会先判断左子树是否已经被访问过,所以我们需要对已经访问过的节点进行标记。对于LeetCode上的原题(网址https://oj.leetcode.com/problems/binary-tree-preorder-traversal/)来说,具体代码过程如下:

public List<Integer> preorderTraversal(TreeNode root) {
		List<Integer> result = new LinkedList<Integer>(); // List to save the result of Binary Tree Preorder Traversal
		if(root == null) {
			return result;
		}
		
		Set<TreeNode> set = new HashSet<TreeNode>(); // Set to save the TreeNode that has been visited.
		Stack<TreeNode> stk = new Stack<TreeNode>(); // Stack to allow to step back to previous TreeNode
		TreeNode currentNode;
		
		// First, visit the root
		set.add(root);
		stk.push(root);
		result.add(root.val);

		while(!stk.isEmpty()) {
			currentNode = stk.peek(); // Get the top TreeNode that has been visited but not pop it.
			while(currentNode.left != null && !set.contains(currentNode.left)) { // Has left child but not been visited, just visit it!
				currentNode = currentNode.left;
				set.add(currentNode);
				stk.push(currentNode);
				result.add(currentNode.val);
			}
			// Visit until the left is null
			// Check whether has right child and if it is visited
			if(currentNode.right != null && !set.contains(currentNode.right)) {
				currentNode = currentNode.right;
				set.add(currentNode);
				stk.push(currentNode);
				result.add(currentNode.val);
			} else { // Has no right child, just pop it out
				stk.pop();
			}
		}
		return result;
	}


          后序遍历也来分析一下。后序遍历需要先遍历左子树,再遍历右子树,最后才是访问当前节点,和前序遍历一样,也是需要栈的支持,保存当前节点,然后左子树非空访问左子树,左子树非空访问左子树。。。直到左子树为空,然后访问右子树;在右子树访问完了之后才访问该节点。对于LeetCode上的原题(网址https://oj.leetcode.com/problems/binary-tree-postorder-traversal/)来说,具体代码如下:

public List<Integer> postorderTraversal(TreeNode root) {
		List<Integer> result = new ArrayList<Integer>();
		if(root == null) {
			return result;
		}
		
		Set<TreeNode> set = new HashSet<TreeNode>();
		Stack<TreeNode> stk = new Stack<TreeNode>();
		
		stk.push(root);
		TreeNode currentNode;
		
		while(!stk.isEmpty()) {
			currentNode = stk.peek(); // Get the top TreeNode but not pop it
			while(currentNode.left != null && !set.contains(currentNode.left)) { // Walk until left child is null, and check whether it has been visited
				stk.push(currentNode.left);
				currentNode = currentNode.left;
			}
			if(currentNode.right != null && !set.contains(currentNode.right)) { // push the right child if it has not been visited
				stk.push(currentNode.right);
			} else {                             // Has no right child or it has been visited before, just visit it!
				set.add(currentNode);
				result.add(currentNode.val);
				stk.pop();
			}
		}
		return result;
	}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值