本文要点:

二叉树三种遍历方式(前序、中序、后序)的非递归实现


ps:递归方法实现:递归法实现二叉树的创建与遍历


非递归的实现需要借助栈!!

前序:

首先需要判断是否是空树,是空返回;否则从根部一直向树的左子树方遍历,遍历一个访问一个,并且将其压入栈。当树不为空,并且栈不为空时,说明栈里仍有元素可访问。


	void _PrevOrder_NonR(Node* root)	//非递归--前序
	{
		if(root == NULL)
			return ;
		Node* cur = root;
		stack<Node*> s;
		while (cur || !s.empty())		//cur != NULL说明仍然有子树可以被遍历
							//!s.empty()  说明栈不为空时可以有数据被访问
		{
			while (cur)
			{
				cout<<cur->_data<<" ";
				s.push(cur);
				cur = cur->_left;
			}

			Node* top = s.top();
			s.pop();
			cur = top->_right;	//访问当前根节点的右子树
		}
		cout<<endl;
	}
中序:

中序的过程与前序相似,只是访问数据的时间不同。中序是先入栈再访问,即当左子树入栈以后才访问

	void _InOrder_N0nR(Node* root)		//非递归--中序
	{
		if(root == NULL)
			return ;
		Node* cur = root;
		stack<Node*> s;
		while(cur || !s.empty())
		{
			while(cur)
			{
				s.push(cur);
				cur = cur->_left;
			}

			Node* top = s.top();	//此时栈顶存的是当前子树的根节点
			cout<<top->_data<<" ";
			s.pop();
			cur = top->_right;	//将右子树作为左子树的子树来遍历
		}
		cout<<endl;
	}
后序:

三种非递归遍历中,后序遍历是比较难理解的。后序遍历必须保证左子树和右子树都访问完以后才能访问根节点,而能访问根节点的可能是有两种:右子树已经被访问或者当前根节点的右子树为NULL。因此,就需要一个标记位pos,当当前根节点右子树和pos相等时,说明已经可以访问该根节点了。

void _PostOrder_NonR(Node* root)	//非递归--后序
	{
		Node* cur = root;
		Node* pos = root;
		stack<Node*> s;
		while (cur || !s.empty())
		{
			while (cur)
			{
				s.push(cur);
				cur = cur->_left;
			}

			Node* top = s.top();

			if (top->_right == NULL || top->_right == pos)
				//top存的是当前的根节点,当top的右子树为空或者top的右子树为pos,说明右子树已经遍历过,
				//这时就可以访问当前的根节点了
			{
				cout<<top->_data<<" ";
				pos = top;
				s.pop();
			}
			else
			{
				cur = top->_right;
			}
		}
		cout<<endl;
	}


本文转载:CSDN博客