Recursion 链表:使用递归

Recursion 链表:使用递归,recursion,linked-list,Recursion,Linked List,我不熟悉链表。我正在尝试编写一个CopyList()代码,可以将链接列表复制到新列表。有一个使用递归的独特版本,我真的不明白: struct node { int data; struct node *next; }; struct node* CopyList(struct node* head) { struct node* current = head; if (current == NULL) return NULL; else { st

我不熟悉链表。我正在尝试编写一个CopyList()代码,可以将链接列表复制到新列表。有一个使用递归的独特版本,我真的不明白:

struct node
{
    int data;
    struct node *next;
};

struct node* CopyList(struct node* head) {
   struct node* current = head;

   if (current == NULL) return NULL;
   else {
      struct node* newList = malloc(sizeof(struct node));
      newList->data = current->data;
      newList->next = CopyList(current->next); // recur for the rest
      return(newList);
   }
}
我难以理解的是行newList->next=copyrist(当前->下一步);
那么这是如何进行复制的,为什么呢?

让我们举个例子。如果您只需将当前->下一步放入新列表->下一步 i、 e

新建列表->下一步=当前->下一步。然后它将只指向旧列表的下一个节点。不发送到新列表的下一个节点。
所以要制作一个不同的列表(复制列表)。您必须单独创建一个新节点,并将其返回到上一个节点的下一个节点

让我们举个例子。如果您只需将当前->下一步放入新列表->下一步 i、 e

新建列表->下一步=当前->下一步。然后它将只指向旧列表的下一个节点。不发送到新列表的下一个节点。
所以要制作一个不同的列表(复制列表)。您必须单独创建一个新节点,并将其返回到上一个节点的下一个节点

这是递归步骤。前两个命令创建一个新节点,并将当前列表的头复制到该对象。现在,我们调用CopyList来复制列表的其余部分,而不是遍历(循环)列表的其余部分——除了刚才复制的head节点之外的所有内容


CopyList返回剩余部分的副本,我们只需将其附加到head节点的副本中即可。。。我们完成了。

这是递归步骤。前两个命令创建一个新节点,并将当前列表的头复制到该对象。现在,我们调用CopyList来复制列表的其余部分,而不是遍历(循环)列表的其余部分——除了刚才复制的head节点之外的所有内容


CopyList返回剩余部分的副本,我们只需将其附加到head节点的副本中即可。。。我们完成了。

这是神奇的递归语句

新建列表->下一步=复制列表(当前->下一步); 对于每个递归步骤,这将将创建剩余链表的任务委托给下一个递归调用

例如:从右到左创建列表

CopyList (1->2->3->4->5)
|
|---------1-> CopyList (2->3->4->5)
              |
              |---------2-> CopyList (3->4->5)
                            |
                            |---------3-> CopyList (4->5)
                                          |
                                          |---------4-> CopyList (5)
                                                        |
                                                        |---------5-> CopyList (NULL)

                                                                  Returns 5
                                                    Returns 4->5->NULL
                                      Returns 3->4->5->NULL
                         Returns 2->3->4->5->NULL
           Returns 1->2->3->4->5->NULL
根据维基

  • 一个或多个简单的基本情况-不使用递归生成答案的终止情况

  • 一组规则,用于将所有其他案例简化为基本案例

    在您的例子中,终止场景是如果列表到达末尾,只返回null,并且在将列表引导到基本场景的每一步都创建一个新节点


  • 这就是神奇的递归语句

    新建列表->下一步=复制列表(当前->下一步); 对于每个递归步骤,这将将创建剩余链表的任务委托给下一个递归调用

    例如:从右到左创建列表

    CopyList (1->2->3->4->5)
    |
    |---------1-> CopyList (2->3->4->5)
                  |
                  |---------2-> CopyList (3->4->5)
                                |
                                |---------3-> CopyList (4->5)
                                              |
                                              |---------4-> CopyList (5)
                                                            |
                                                            |---------5-> CopyList (NULL)
    
                                                                      Returns 5
                                                        Returns 4->5->NULL
                                          Returns 3->4->5->NULL
                             Returns 2->3->4->5->NULL
               Returns 1->2->3->4->5->NULL
    
    根据维基

  • 一个或多个简单的基本情况-不使用递归生成答案的终止情况

  • 一组规则,用于将所有其他案例简化为基本案例

    在您的例子中,终止场景是如果列表到达末尾,只返回null,并且在将列表引导到基本场景的每一步都创建一个新节点


  • 第一!将电流更改为head。电流没有定义。首先!将电流更改为head。电流没有定义。