我对递归的工作原理有一点了解。调用以及堆栈提供的变量的不同上下文,用于存储前一个被调用函数返回的值。
例如,
void Factorial(int n)
{
if(n==0) return 0;
else if(n==1) return 1;
else
{
return n*Factorial(n-1);
}
}
在这个用于计算给定数的阶乘的递归函数中,我知道假设给定n为5的第一次调用将是5 *因子(4 *因子(3 ....所以直到它到达任何基本条件))然后它将按顺序遍历返回值,例如1 * 2 * 3 * 4 * 5 = 240。
我无法理解的是这段代码以相反的顺序打印单链表的项目。
void ReversePrint(Node head) {
if(head==null)
{
return;
}
else
{
ReversePrint(head.next);
System.out.println(head.data);
}
}
据我所知,链表函数中的元素数量有限,如
首先, 因为head不是null,所以它将转到else条件,head将等于head.next,直到它变为null。什么呢?
我可能不会用确切的语言表达我的问题。希望你能解释一下。提前谢谢。
答案 0 :(得分:2)
添加一些额外的评论应该会有所帮助:
void ReversePrint(Node node) {
if (node == null) {
// An empty list has nothing to print.
return;
} else {
// First print the rest of the list.
ReversePrint(node.next);
// Then print this node.
System.out.println(node.data);
}
}
所以 - 基本上 -
导致列表向后打印。
答案 1 :(得分:0)
想象一下,你有一个名为ReversePrintRest
的函数,它会获取一个列表并打印所有但的头部。然后你可以很容易地写ReversePrint
:
void ReversePrint(Node head) {
if(head==null) {
return;
} else {
ReversePrintRest(head);
System.out.println(head.data);
}
}
只要ReversePrintRest
像宣传的那样工作,我就会认为你同意这个有效是没有问题的。
关于如何编写ReversePrintRest
,这也很简单:
void ReversePrintRest( Node head ) {
ReversePrint( head.next );
}
同样,假设ReversePrint
有效,也很容易看出正确性。由于ReversePrintRest
的正文是直接从原始代码中获取的,因此原始代码也应该是正确的。
这似乎有些狡猾:每个功能的正确性取决于其他功能。但我们可以更明确地了解ReversePrint
:
只留下假设:
只要您需要任何长度为N的列表,您就可以遵循该逻辑。由于参数不依赖于N的特定值,因此它适用于所有这些值。
答案 2 :(得分:-1)
这个问题可能有很多重复,但不是找到它们并将它们联系起来,我想解决一些与你所问的问题有关的问题。
对于阶乘示例,递归很有效,因为通常你不想计算非常高的阶乘,如果你确实希望你在进入堆栈之前经常遇到整数溢出溢出。
但是,列表的大小通常大于1000个元素。对于我的实现,ReversePrint方法给了我一个大于大约10000个元素的StackOverflowError链表,这是由于Java限制了内存中的堆栈大小。
对于像这样的应用程序,通过使用类似这样的东西,非递归地执行它会好得多:
ReversePrint(YourList l) {
Node n = l.last;
while (n != null) {
System.out.println(n.data);
n = n.prev;
}
}
请注意,完成此类操作需要一些其他功能。列表必须是双向链接,包括向前和向后,并且必须有某种类型的YourList类来封装它(为简单起见)。