使用递归从末尾(链接列表)的第n个节点

时间:2015-01-05 14:09:58

标签: c recursion linked-list

任何人都可以解释这实际上是如何运作的。我无法理解递归,在递归到达链表的末尾之后会发生什么以及如何与操作一起进行展开(增量和条件检查)?

Linked List

void printNthFromLast(struct node* head, int n) 
{
static int i = 0;
if(head == NULL)
   return;
printNthFromLast(head->next, n);
if(++i == n)
   printf("%d", head->data);
}

2 个答案:

答案 0 :(得分:0)

在我看来,这是一个功能很差的功能,但我会尝试解释我是如何看待它的。

基本上你将多个递归函数推到一个堆栈上,直到你遇到基本情况,然而你只是每次弹出大约一半的函数,剩下的就在下一个函数之后完成。当您点击基本情况时,不再发生递归,您必须返回堆栈,弹出每个函数,直到您处于父函数,它将完成并且您已完成。

答案 1 :(得分:0)

如果传递给它的struct node *为NULL,则返回该函数。如果链接列表的节点数为零或者我们已到达链表的末尾,则会发生这种情况。

if(head == NULL)
    return;

否则,该功能的每个实例都将在此行等待它的孩子'返回:

printNthFromLast(head->next, n);

在我们到达列表末尾之前不会进行打印。一旦我们到达列表的末尾,调用的最后一个函数将在if语句上返回,因为head == NULL,因为我们在最后。

现在,该函数的每个实例都将继续执行这些行(一旦它已经返回了孩子'

if(++i == n)
    printf("%d", head->data);

它基本上从后面算起。每个实例将i递增1,然后检查它是否等于我们提供的数字n。如果是,则打印数据。否则,它就结束了,而且它的父母是'有机会执行这些行。

编辑:这实际上是一种非常糟糕的方式来做你正在做的事情。如果列表相当大,您的程序可能会耗尽堆栈内存。你应该通过迭代来做到这一点。