我有一个关于return和递归函数的问题。
这也是基于我目前正在研究的二叉树。代码是
void Tree::display()
{
if( !root_ )
return;
display_r(root_);
}
void Tree::display_r(Tree *node)
{
if( 0 == node )
return;
display_r(node->left_);
std::cout << node->value_ << std::endl;
display_r(node->right_);
}这是正常工作的代码。编译并无故障运行,从最小到最大打印数字。然而,这并不是过去的情况。
上面的代码最初是用
return display_r(node->left_);
std::cout << node->value_ << std::endl;
return display_r(node->right_);但这并不管用。它只是返回而不打印任何内容。这是有道理的,返回不允许代码向下移动。
这就引出了一个有趣的问题。在编写树时,我经常想知道在递归函数中使用return是否是一个好地方。显然,只要return是在代码块中执行的最后一个命令,就可以使用。我认为甚至可以在display()函数中使用
void Tree::display()
{
if( !root_ )
return;
return display_r(root_);
}所以我的问题是:我什么时候确定我可以使用return,什么时候我不应该使用它?是否存在灰色地带,由我来决定什么是最好的,是否有安全网?例如,“当有疑问时,不要在递归函数中使用返回?”
谢谢!
发布于 2010-06-27 15:34:39
我总是发现在编写递归函数时考虑数学归纳是很有帮助的:你需要一个基本情况和一个归纳情况才能使归纳工作。递归没有太大的不同:您需要一个方法/例程/函数来将问题减少到基本情况,并且您需要一个方法/例程/函数来处理基本情况。
换句话说,你需要一些东西来终止递归函数,并且你需要一些东西来使当前的输入达到终止状态。
一旦你明白了这一点,就更容易考虑把return语句放在哪里了:
当你的所有函数都返回'void‘时,在这种情况下,它们返回的内容并不重要。如果你把'return‘语句放在它们自己的行上,你可能会更容易查看你的代码。(您的代码几乎给人一种'return‘被用作'goto’或'call‘语句的印象。)
当您的函数返回数据时(而不是执行副作用,例如打印),那么您可能会更清楚返回语句的位置:它们必须在您计算了所处理的用例所需的数据之后才能使用,无论是基本用例还是归纳用例。
您可能会发现,学习具有树结构的“广度优先搜索”和“深度优先搜索”以及“前排序”、“按顺序”和“后排序”树遍历会很有帮助。一开始可能听起来有点吓人,但迟早都会点击,而且递归函数对你来说会容易得多。:)
https://stackoverflow.com/questions/3126669
复制相似问题