递归转换成非递归思路

问题:

非常经典的问题,将一个二叉树遍历,前序,中序,后序遍历由递归转换成非递归。

分析:

递归转换成非递归,一般解法是自己使用栈去模拟递归过程,首先我们来看下后序遍历递归解法:

void postOrderTraverse(pNode root)

{

if(root == NULL)

return ;

postOrderTraverse(p->left);

postOrderTraverse(p->right);

visit(p);

return ;

}

从上面递归过程可以看出来,首先是从左子树一直递归下去,知道为空,然后从栈中返回一个节点,再从这个节点的右节点进行遍历,最后才访问根节点,这里后序遍历的非递归算法,需要一个小trick,p自身需要做个标记,标记当前的右节点是否已经遍历,如果没有遍历,执行右节点任务,如果已经执行,可以访问自己。

代码如下:

void PostTraverse(BINARYTREE p)
{
	while (p != NULL || !Stack.IsEmpty()) //存在工作(手头或待完成)   
	{
		while (p != NULL) 				//处理手头工作,直到无现成手头工作   
		{
			Stack.Push(p, RCHILD_AND_ITSELF);
			p = p->LChild;
		}
		if (!Stack.IsEmpty()) 			//是否存在待完成工作   
		{
			Stack.Pop(p, Tag);
			if (Tag == RCHILD_AND_ITSELF) //情况一:   RChild   &   Itself   
			{
				Stack.Push(p, ONLY_ITSELF)
				//保存待完成工作   
				p = p->RChild; 			//新的手头工作   
			}
			else //tag   ==   ONLY_ITSELF, 情况二:   Only   Itself   
			{
				visit(p);
				p = NULL; 				//已无现成的手头工作   
			}
		}
	}
}   

总结:

从上面代码可以看出,递归转换成非递归,我们需要使用栈来模拟。

用一个指针变量保存当前执行的任务,p

用一个栈保存将要执行的任务,Stack

如果p为NULL了,说明当前手头没有任务,我们需要从Stack中选择一个任务,如果Stack为空,说明当前所有任务都已经完成

理解了手头任务和待完成任务,自行用栈模拟就比较好理解、实现了。

你可能感兴趣的:(算法)