递归转换成非递归思路

来源:互联网 发布:数据库序列如何创建 编辑:程序博客网 时间:2024/05/01 19:31

问题:

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

分析:

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

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为空,说明当前所有任务都已经完成

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

原创粉丝点击