【问题标题】:Linked List: Copy List Using Recursive链表:使用递归复制列表
【发布时间】:2016-07-19 17:37:37
【问题描述】:

我是链表的新手。我正在尝试编写可以将链接列表复制到新列表的 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 = CopyList(current->next); 那么这对复制有什么作用?为什么?

【问题讨论】:

  • 第一!将电流改为头部。 current 在任何地方都没有定义。

标签: recursion linked-list


【解决方案1】:

让我们举个例子。如果您只是将 current->next 放入 newList->next 即

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

【讨论】:

    【解决方案2】:

    这是神奇的递归语句。

    newList->next = CopyList(current->next);

    对于每个递归步骤,这会将创建剩余链表的任务委派给下一个递归调用。

    例如:列表是从右到左创建的。

    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
    

    根据维基

    1. 一个简单的基本案例(或多个案例)——一个不使用递归来产生答案的终止场景。

    2. 一组将所有其他情况减少到基本情况的规则。

      在您的情况下,终止方案是如果列表到达末尾,则返回 null 并在将列表引导至基本方案的每一步创建一个新节点。

    【讨论】:

      【解决方案3】:

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

      CopyList 返回该剩余部分的副本,我们只需将其附加到头节点的副本......我们就完成了。

      【讨论】:

        猜你喜欢
        • 2022-11-12
        • 1970-01-01
        • 1970-01-01
        • 2018-12-03
        • 1970-01-01
        • 2017-04-21
        • 1970-01-01
        • 2020-07-22
        • 2013-03-28
        相关资源
        最近更新 更多