二叉树的后序非递归遍历

    二叉树在面试中很容易被问到,三种遍历的非递归版本,最近就遇到了二叉树的后续非递归遍历,所以我就将二叉树的后续非递归遍历实现了一下,代码如下:

/*二叉树的后续非递归遍历*/

//二叉树节点的结构,我使用模板实现的,这样复用性较好
template<class T>
struct BinTreeNode
{
	T					_value;
	BinTreeNode<T>*		left;
	BinTreeNode<T>*		right;

	BinTreeNode(const T& val) 
		: _value(val)
		, left(NULL)
		, right(NULL)
	{}
};

#include <stack> //当然一般是在头文件中引入的,但是这里只是实现一个函数,所以就在函数前面引入一下
template<class T>
void PostOrder(BinTreeNode<T>* t)
{ //t是树的根节点
	assert(t); //判断t是否合法
	stack<BinTreeNode<T>*> S; //使用stack来实现非递归后续遍历
	BinTreeNode<T>* cur = t;
	BinTreeNode<T>* visitedNode = NULL; //标记已经被访问的节点,用于标记右边的节点被访问过
	while (cur || !S.empty())
	{
		// 当前节点不为空,一直压栈,切不断往左子树深入
		while (cur)
		{
			S.push(cur);
			cur = cur->left;
		}
		//左子树为NULL时停止,这就是左子树为NULL的情况
		t = S.top(); //取栈顶元素		
		/*
		 *右孩子为空或被访问过则输出,而且当以下两个条件满足时才能输出当前节点,其中
		 * t->right == NULL说明该节点没有右子树了,该节点需要被打印;
		 *t->right == visitedNode时说明右子树已经遍历过,满足后续遍历要求。
		 */
		if (t->right == NULL || t->right == visitedNode) 
		{ 
			cout << t->_value << " ";
			S.pop();
			visitedNode = t;  //标记该节点被访问过
		}
		else
		{ //说明该节点还存在右子树,我们应该去右子树中寻找下一个打印的节点
			cur = t->right;
		}
	}
}


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