二叉树后序非递归遍历

二叉树的后序遍历比二叉树的先序和中序遍历要麻烦一些。同样要用到栈(stack),但每个节点要进栈两次,出栈两次,在第一次出栈时并不访问,而是去找他的右子树,只有在第二次出栈时才进行访问,原因是第一次出栈时只是访问完了左子树,第二次出栈表示访问完了右子树。以下图为例后序操作为:

1、首先沿根节点(下图中的A)的左子树一直向下找,直到最左节点D,沿途的节点都进栈,依次为:A先进栈,B进栈,D进栈。并标记这些节点为第一次进栈

2、D出栈(第一次出栈),检查D的进栈状态为第一次进栈,所以先不访问D,将D重新放入栈中,并标记D为第二次进栈。并进入D的右子树(此时为空)。

3、因为D的右子树为空,程序又进行到出栈操作,D出栈,因为时第二次出栈,所以访问D。

4、继续出栈,B第一次出栈,不访问,B第二次进栈,进入B的右子树,E进栈,出栈,进栈,出栈,访问E。

5、B第二次出栈,访问B。

6、...以此类推。

                二叉树后序非递归遍历_第1张图片

下面是Java实现的二叉树的后序遍历,新定义了StackNode结构,表示存放在栈中的节点状态,isFirst表示是不是第一次进栈。变量continuePop表示是不是要继续出栈,如果刚刚出栈的元素是第一次出栈,则值为false,因为要进入其右子树,如果刚刚出栈的元素时第二次出栈,表示右子树访问完毕。则继续出栈。

/**
 * Definition for binary tree
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class PostorderTraversal {
	
	public class StackNode{
		TreeNode node; 
		boolean isFirst;		//ture:first time enter stack,false:second time
		StackNode(TreeNode node,boolean isSecond){
			this.node = node;
			this.isFirst = isSecond;
		}
	}
	
	ArrayList<Integer> list = new ArrayList<Integer>();
	Stack<StackNode> stack = new Stack<StackNode>();
	
    public List<Integer> postorderTraversal(TreeNode root) {
        if(root==null){
        	return list;
        }
        
        StackNode sNode = null;
   
        do{
	        while(root!=null){
	        	stack.push(new StackNode(root,true));
	        	root = root.left;
	        }
	        
	        boolean continuePop = true;
	        
	        while(continuePop && !stack.isEmpty()){
	        	sNode = stack.pop();
	        	if(sNode.isFirst){
	        		continuePop = false;
	        		sNode.isFirst = false;
	        		stack.push(sNode);
	        		root = sNode.node.right;
	        	}else{
	        		list.add(sNode.node.val);
	        	}
	        }
        }while(!stack.isEmpty());
        
    	return list;
    }
    
//    public static void main(String[] args) {
//		TreeNode root = TreeNode.getInstance();
//		PostorderTraversal sot = new PostorderTraversal();
//		System.out.println(sot.postorderTraversal(root));
//	}
}


你可能感兴趣的:(二叉树后序非递归遍历)