递归中静态变量的行为

时间:2014-07-17 15:50:46

标签: c++ recursion data-structures stack

我在谈论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都重新初始化了功能堆栈吗?

2 个答案:

答案 0 :(得分:2)

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

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

关于您的实施,您首先要先左转,然后先右转。在您要打印的行之前的行中,level始终等于1,因此您始终从右向左遍历打印行。当你有一个更深的树时,你会看到更大的节点混乱。在纸上绘制一个样本树,并在手动操作代码时在其上绘制导航。

答案 1 :(得分:1)

  

我知道如果在递归中将int声明为const,则它的值不会在stack-recursion调用中重新初始化,并且会使用当前值。

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

  

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

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

static局部变量显示您正在描述的行为:它们仅在第一次调用该函数时执行一次,并且重要的是,即使在调用之后它们也不会重新初始化堆栈被“清空”。无论是从外部还是递归地重复调用函数都没有区别。