递归中静态变量的行为

Behaviour of static variables in recursion

本文关键字:变量 静态 递归      更新时间:2023-10-16

我指的是c++。我知道,如果在递归中将int声明为静态,则在堆栈递归调用中不会重新初始化其值,而是使用当前值。

但是如果堆栈变为空(或递归计算完成),然后再次调用递归,它会使用与第一次堆栈调用初始化时相同的静态值吗?

我将详细解释我的问题。

我正在尝试以螺旋形式编码水平顺序遍历。

         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-call。但在整个代码中,它总是使用k=1(在第一次LevelSpiral-call中初始化i=1),并将输出打印为1 3 2 4 5 6 7。

它不应该打印1 2 3 4 5 6 7为每个i函数堆栈重新初始化?

您需要一个静态变量,以便在调用之间或从一个调用到下一个递归调用之间保留其值。

此外,递归不会是广度优先遍历的首选工具。我将使用节点(安全)指针队列(或引用包装器或其他)。将根节点放入队列中,然后循环直到队列为空,删除前面的元素并将它的所有子节点放入队列中,然后对最近删除的元素执行您想要的操作。

关于你的实现,你在先向左和先向右之间交替。在要打印的行之前,Level总是等于1,所以总是从右向左遍历打印行。当你有一个更深的树时,你会看到更大的节点洗牌。在纸上绘制一个示例树,并在上面绘制导航,同时手工编写代码。

我知道,如果在递归中将int声明为const,则在堆栈递归调用中不会重新初始化其值,而是使用当前值。

不,那是错的。const与递归或重入无关。

但是如果堆栈变为空(或递归计算完成),然后再次调用递归,它会使用与第一次堆栈调用初始化时相同的const值吗?

const是一个正常的(尽管是不可修改的)变量:每当执行初始化语句时,即在每次函数调用时,它都会被重新初始化。对于任何static变量都是一样的。

static局部变量表现出您所描述的行为:它们只执行一次,在该函数的第一次调用,而且,重要的是,即使在调用堆栈被"清空"之后,它们也不会被重新初始化。无论从外部重复调用函数还是递归调用函数都没有区别。