Recursion 递归函数如何在具有堆栈概念的链表中工作?

Recursion 递归函数如何在具有堆栈概念的链表中工作?,recursion,linked-list,function-call,Recursion,Linked List,Function Call,这里我给出了一个代码来打印链接列表的反面 fun1()以相反的方式打印给定的链表。对于链表1->2->3->4->5,fun1()打印5->4->3->2->1 void fun1(struct node* head) { if(head == NULL) return; fun1(head->next); printf("%d ", head->data); } 有人能解释一下每次调用fun1()时堆栈框架是如何构建的吗? 我希望链表的最后一个节点会打印出

这里我给出了一个代码来打印链接列表的反面

fun1()以相反的方式打印给定的链表。对于链表1->2->3->4->5,fun1()打印5->4->3->2->1

void fun1(struct node* head)
{
  if(head == NULL)
    return;

  fun1(head->next);
  printf("%d  ", head->data);
}
有人能解释一下每次调用fun1()时堆栈框架是如何构建的吗?
我希望链表的最后一个节点会打印出来。但我得到的链表顺序相反。它不会使链表反转。它只是反向打印。我认为这是由于像Push/Pop这样的堆栈操作造成的。但我不太清楚。请通过图表中的逐步操作帮助我理解。

我不太确定您想要实现什么。你的代码准确地打印出它应该做什么。以下是满足您期望的代码段:

我希望链表的最后一个节点会打印出来


如果向其提供列表1->2:

  • head=1->2,head不为空,用2重复出现(继续5)
  • =>head=2,head不为空,重复出现空值(继续4)
  • =>=>head=null,head为null,返回
  • =>打印头->数据“2”并返回
  • 打印头数据“1”并返回
  • 如果要在print语句递归之前移动它:

    void fun1(struct node* head)
    {
      if(head == NULL)
        return;
    
      printf("%d  ", head->data);
      fun1(head->next);
    }
    
    是这样的:

    void print_last(struct node* n)
    {
        if( n == NULL )
        {
            printf("empty list!");
        }        
        else if( n->next == NULL )
        {
            printf("%d", n->data);
        }
        else
        {
            print_last(n->next);  
        }
    }
    
  • 磁头=1->2,磁头不为空,打印磁头->数据“1”,重复出现2(续5)
  • =>磁头=2,磁头不为空,打印磁头->数据“2”,以空值重复出现(续4)
  • =>=>head=null,head为null,返回
  • =>返回
  • 返回
  • 在这两种情况下,都会打印所有非空节点。要仅打印其中一个,代码必须将其与另一个区分开来,如下所示:

    void print_last(struct node* n)
    {
        if( n == NULL )
        {
            printf("empty list!");
        }        
        else if( n->next == NULL )
        {
            printf("%d", n->data);
        }
        else
        {
            print_last(n->next);  
        }
    }
    
    使用您得到的相同列表1->2调用

  • n=1->2,n!=空和n->下一步!=null,与2重复出现(在3上继续)
  • =>n=2,n!=null和n==null。打印n->数据“2”并返回
  • 返回

  • 请注意,当找到最后一个元素时,它不会递归,因此n为null的唯一方法是,如果您尝试打印空链表(null)。

    这个问题不清楚。如果代码以相反的顺序打印列表的内容,则不会尝试以相反的顺序重新生成列表。这似乎让你感到惊讶。您是否要求使用代码来实际反转列表?或者对当前代码如何工作的解释?