为什么我的递归函数按降序打印,然后按升序打印?

Why does my recursive function print in descending order and then in ascending order?

本文关键字:打印 然后 升序 降序 我的 递归函数 为什么      更新时间:2023-10-16

我有一个简单的递归c++程序,我试图确切地理解它是如何工作的。我明白为什么程序打印出3 2 1,但是我不明白为什么它会以另一种方式打印1 2 3.我使用手动模拟并逐步浏览了该程序,但仍然不明白1 2 3是如何产生的。我从GeeksForGeeks找到了这篇文章,但仍然难以掌握这个概念。任何解释都会很棒。

#include <iostream>
using namespace std;
void test(int n)
{
if (n > 0)
{
cout << n << " ";
test(n - 1);
cout << n << " ";
}
}
int main()
{
test(3);
return 0;
} 

递归中函数调用的顺序如下所示:

test(3)
-- cout << 3 << " ";
-- test(2)
-- -- cout << 2 << " ";
-- -- test(1)
-- -- -- cout << 1 << " ";
-- -- -- test(0)
-- -- -- cout << 1 << " ";
-- -- cout << 2 << " ";
-- cout << 3 << " ";

将程序更改为

#include <iostream>
using namespace std;
void test(int n)
{
if (n > 0)
{
cout << "enter" << n << " ";  // <- add "enter" here
test(n - 1);
cout << "exit" << n << " ";   // <- add "exit" here
}
}
int main()
{
test(3);
return 0;
} 

您将看到下一个输出

enter3 enter2 enter1 exit1 exit2 exit3

您可以将递归调用视为堆栈的操作。 有两种操作:pushpop。 您的程序的作用是

push test 3
push test 2
push test 1
pop test 1
pop test 2
pop test 3

在每个pushpop,您都会cout,从而看到输出3 2 1 1 2 3

在这里,您可以找到有关递归的更多信息。

问题是所有的答案都对你没有帮助,因为即使有人向你解释了它,你也会陷入下一个算法。

我提供了一种基本方法,对我理解一些搜索算法、链表、二叉树等有很大帮助,因为我是一个简单的头脑。

你要做的是找出以你能想出的最有创意的方式表示数据的方法。因为编程只是以多种方式翻转数据。我想出的几个例子是使用塑料罐并张贴它或葡萄和盘子,我见过一些印度视频家伙在图表上绘制数据流,或者如果你愿意,只是在一张不同颜色的纸上画圆圈 其工作原理如下:

  1. 将数据放在帖子上,每轮一个。你有一个简单的算法,我会写一个"3",因为它是通过函数传递的。
  2. jars,代表函数调用,我会为每次调用取一个jar。
  3. 一点
  4. 一点地模拟算法。就像在罐子上贴上 3 一样 ->第一个 cout "3" ->测试被称为"n - 1",所以"2"进入一个新的罐子(在帖子上写 2( ->第二个 cout "2" ->测试被称为"n - 1",因此 1 在新罐子中再次出现。(在帖子上写 1( ->第三个 cout "1" -> 测试被称为"n - 1",所以 0 进入一个新的罐子。(在帖子上写 0( - 但等等!0 不大于 0!这样那个罐子就不会传递 if 命令!所以测试不会再次被调用 - 函数结束。 现在看看你的地方!你仍然有 4 个 jar,函数中的第二个 cout 甚至没有被调用一次 - 现在是时候了,因为每个 jar 代表一个尚未完成但仍打开的函数调用。你最后放进的罐子里是什么数字?对,一个1!所以"1"进入了cout。揉碎帖子,把罐子放回去。下一个罐子里有什么?一个"2"?宾果游戏 - 通过第二个 cout 打印。最后一个杯子里有3?- 对,用 cout 打印它,而不是把它揉成一团。没有杯子了?没有要打印的数据?你完成了! 这就是程序的工作原理! 恭喜,因为我相信你现在已经掌握了!:)

顺便说一句,如果您不知道数据流向何处,每个好的IDE都有一个调试器,可让您准确地运行程序执行的步骤,并在每一步之后停止。在 alex allain 中使用调试器"跳转到 c++"中解释得非常好,他有一整章关于如何阅读和编写程序,还有一整章关于递归,我认为 6 个仅用于指针。他给出了寻找表示数据的方法的提示,我希望这对您有所帮助,就像它对我有帮助一样:)

干杯

这是因为在if 语句中调用 "test" 方法后有了 cout 语句。在它遍历所有方法调用并达到基本情况后,它会以调用方法的相反顺序返回每个方法调用移动到下一行(cout 语句(。

为了清楚起见,重写函数

void test( unsigned int n )
{
if ( n )
{
std::cout << n << " ";
test( n - 1 );
std::cout << n << " ";
}
}

以下方式

void test( unsigned int n )
{
if ( n )
{
std::cout << n << " ";
std::cout << n << " ";
test( n - 1 );
}
}

那就是移动第二条语句

std::cout << n << " ";

声明上方

test( n - 1 );

对于修改后的函数的调用test( 3 );,您将获得以下输出

3 3 2 2 1 1 

因此,函数的每次递归调用两次都会输出传递的值 n。我希望它很清楚,因为该函数明确包含相同的语句两次

std::cout << n << " ";
std::cout << n << " ";

现在回到原始函数定义,我们看到在相同值的两个输出之间,函数n值调用自身n - 1.

因此,每个函数调用输出相同的值两次,但在输出之间,函数递归调用自身。

现在输出可能看起来像

3         3
|
call itself for 2 

。等等。

相关文章: