C 堆栈上的递归函数
我有一个非常简单的函数来计算一堆整数的最大值,非负值。我想把这个函数转换成递归函数。 有几点需要记住:C 堆栈上的递归函数,c,recursion,stack,iteration,C,Recursion,Stack,Iteration,我有一个非常简单的函数来计算一堆整数的最大值,非负值。我想把这个函数转换成递归函数。 有几点需要记住: 在运行函数之前,我们已经初始化了num,但没有为其分配任何值。请注意,我们不应该依赖这样一个事实:在某些条件下,C会自动将0分配给num 运行函数后,堆栈s为空,我们将最大非负值存储在num 我是C和数据结构的初学者,所以请友好:) 这是迭代函数: void max_stack(stack *s, int *num){ *num = 0; int aux = 0;
- 在运行函数之前,我们已经初始化了
,但没有为其分配任何值。请注意,我们不应该依赖这样一个事实:在某些条件下,C会自动将0分配给num
num
- 运行函数后,堆栈
为空,我们将最大非负值存储在s
num
- 我是C和数据结构的初学者,所以请友好:)
void max_stack(stack *s, int *num){
*num = 0;
int aux = 0;
while (!emptyStack(*s)){
aux = top(*s);
pop(s);
if (aux>*num){
*num = aux;
}
}
}
这样做的方式是,如果堆栈不是空的,那么它将继续调用自身,并向前传递最大值。堆栈为空后,函数将通过num指针逐个返回最大值 此处为伪代码:
void max_stack(stack *s, int * num){
int aux = 0;
if(!emptyStack(*s)){
aux = top(*s);
pop(s);
if (aux > (*num)){
(*num) = aux;
}
max_stack(s, num);
}
}
第一次调用此函数时,您可以这样调用它:
int num = 0
max_stack(s, &num);
为了精确匹配所提供的迭代代码,我们还必须匹配这样的假设,即即使在空堆栈上,0
是将存储在目标参数中的最小值
因此:
void recursive_max_stack(stack *s, int *num)
{
if (emptyStack(*s))
{
*num = 0;
return;
}
int lhs = top(*s);
pop(s);
recursive_max_stack(s, num);
if (lhs > *num)
*num = lhs;
}
解释
首先,我们需要一个默认情况(当堆栈中没有元素时)。与迭代函数一样,默认情况下存储零
if (emptyStack(*s))
{
*num = 0;
return;
}
因此,我们需要在当前帧中保存当前堆栈顶部,然后将其从堆栈中弹出(请记住,我们将其保存在局部变量中):
一旦完成,我们就可以递归
recursive_max_stack(s, num);
从递归返回时,将每个lhs
与*num
的内容进行比较(当我们达到最大深度时,它被设置为0
)。如果更大,lhs
将替换存储在*num
中的值
if (lhs > *num)
*num = lhs;
这将在我们展开调用时继续向上调用堆栈,最后返回到初始调用,然后返回到调用方,*num
现在保留堆栈中最大的非负值,或者如果所有值都为负值(或堆栈为空),则为零
就这样。这与存储在
*num
中的原始值无关。在达到最大递归深度时,它最终被替换为0
,然后在后续帧的lhs
值大于*num
中当前存储的值时再次替换,我不知道为什么要将其转换为递归函数,当您现在的解决方案比递归函数更适合C时,…@AnttiHaapala作业要求可能?@AnttiHappala:我试图更好地理解递归,并且希望更流畅地从迭代函数到递归函数,反之亦然。就这样。这个问题的目的是为了学习。我列举的限制是为了确保这两个函数100%等效。“我们已经初始化了num,但没有给它赋值。”-很难巩固这意味着什么。如果它已初始化,则具有确定的值。另外,num
是此代码中的指针,并且被取消引用,因此它最好包含一个有效地址。如果您谈论的是取消引用的值,那么您肯定会通过*num=0为其赋值代码>最后,迭代函数会找到最大值并清空堆栈。那是故意的?您说过这是最终结果,但只是在这里澄清一下。@whoscratig我的意思是,在调用函数之前,我们只有以下内容:int number/*我们还设置了一个整数堆栈“example_stack”,它可以是满的或空的*/*我们现在调用函数*/max_stack(&example_stack,&number)/*我们现在应该让示例_堆栈为空,堆栈中存储在number*/@Josep I中的最大正值也修复了前一版本中的一个bug,感谢您的响应。但是请注意,该函数并不是100%等价于我发布的迭代函数。关键的一点是“void”函数应该对num的初始值不敏感:在调用函数之前,我们所能做的就是intnum代码>@Josep很好,因为num是一个指针,如果我将原型更改为优秀的解释,它应该仍然有效。我唯一的疑问是为什么我们需要返回在*num=0
@Peter之后,将所有内容放在else
块中,将使返回无效。这只是一种风格选择。您可以采用任何一种方式,但不应该只删除返回代码>并保持代码不变。这行不通。
if (lhs > *num)
*num = lhs;