我在谈论C ++。 我知道如果一个int在递归中被声明为static,那么它的值不会在stack-recursion调用中重新初始化,并且会使用当前值。
但是如果堆栈变空(或者递归计算完成)然后再次调用递归,它是否会使用与第一次堆栈调用中初始化相同的静态值?
我会详细解释我的问题。
我正在尝试以螺旋形式编码级别顺序遍历。
1
/ \
2 3
/ \ / \
7 6 5 4
螺旋形式的水平顺序遍历将给出输出1 2 3 4 5 6 7。
void LevelSpiral(node* root, int level)
{
static int k = level%2;
if(root==NULL)
return;
if(level==1)
{
printf("%d ",root->val);
}
else
{
if(k==0)
{
LevelSpiral(root->left,level-1);
LevelSpiral(root->right,level-1);
}
else
{
LevelSpiral(root->right,level-1);
LevelSpiral(root->left,level-1);
}
}
}
void LevelOrderSpiral(node* root)
{
for(int i=1;i<=maxheight;i++)
LevelSpiral(root,i);
}
LevelOrderSpiral函数为每个i进行单独的LevelSpiral调用。但是在整个代码中它始终使用k = 1(在第一个LevelSpiral调用中初始化,i = 1)并将输出打印为1 3 2 4 5 6 7.
不应该打印1 2 3 4 5 6 7因为每个i都重新初始化了功能堆栈吗?
答案 0 :(得分:2)
您需要一个静态变量,以便在调用之间或从一次调用到下一次递归调用时保留它的值。
此外,递归不是我达到广度优先遍历的第一个工具。我会使用节点(安全)指针(或引用包装器或其他)的队列。将根节点放入队列,然后循环,直到队列为空,删除前面元素并将所有子节点排队,并使用最近删除的元素执行所需操作。
关于您的实施,您首先要先左转,然后先右转。在您要打印的行之前的行中,level始终等于1,因此您始终从右向左遍历打印行。当你有一个更深的树时,你会看到更大的节点混乱。在纸上绘制一个样本树,并在手动操作代码时在其上绘制导航。
答案 1 :(得分:1)
我知道如果在递归中将int声明为const,则它的值不会在stack-recursion调用中重新初始化,并且会使用当前值。
不,那是错的。 const
与递归或重入无关。
但是如果堆栈变空(或者递归计算完成)然后再次调用递归,它是否会使用与第一次堆栈调用中初始化相同的const值?
const
是一个正常的(尽管是不可修改的)变量:只要执行初始化语句,即在每个函数调用上,它都会重新初始化。对于任何非static
变量,这都是相同的。
static
局部变量显示您正在描述的行为:它们仅在第一次调用该函数时执行一次,并且重要的是,即使在调用之后它们也不会重新初始化堆栈被“清空”。无论是从外部还是递归地重复调用函数都没有区别。