昨天做usaco的一道题,把递归函数非递归化看看对效率的提升,对如何转化,做了一些尝试。
理解递归过程
递归是函数调用自己本身,每调用一次自己,就进入一个新的堆栈帧
非递归化
通过观察递归的过程,我们知道这是通过堆栈来实现的,那么非递归化,就是
我们手动构造一个堆栈,在一次函数过程中模拟递归。
既然我们构造堆栈,堆栈要保存什么信息?
保存函数的局部变量,及执行到的语句。
堆栈的维护
每调用一次函数,相对应就要push一个状态,离开函数,就要pop
示例
简单起见,我们首先来看看二叉树遍历的非递归化
首先,二叉树的先序遍历 递归写法:
void preOrder(TreeNode* root)
{
if(root==NULL)
return;
printf("%d ",root->val);
preOrder(root->left);
preOrder(root->right);
}
函数局部变量,只有root,需要保存在自己维护的堆栈,而执行到的位置,此处并不需要保存,因为我们知道函数执行left后,会以right为root进入新的栈帧,那么我们提前把root->right push进自己维护的堆栈就好了.
while循环每一次,就代表执行一次函数
void preOrder(TreeNode* root)
{
stack<TreeNode*> q;
TreeNode* tp;
q.push(root);
while(!q.empty())
{
tp = q.top();
q.pop();
if(tp==NULL)
continue;
q.push(tp->right);
q.push(tp->left);
}
}
我把非递归的版本放进leetcode