如何在不使用递归的情况下将链表复制到另一个列表中

时间:2013-03-11 05:36:38

标签: c data-structures linked-list

我正在研究数据结构和链表,但我没有得到如何在没有递归的情况下制作链表副本的概念。有人可以解释一下。

5 个答案:

答案 0 :(得分:2)

一个简单的迭代逻辑的伪代码将是:

  1. 从原始列表origHead开始。
  2. 设置一个临时指针,指向原始列表的头部tempNode = origHead
  3. 如果tempNode = NULL,请转到第17步。
  4. 如果tempNode != origHead,请转到第10步。
  5. 为副本列表的头部copyListHead分配内存。
  6. copyListHead->next设为NULL
  7. 设置一个临时指针,指向副本列表的头部copyListTempNode = copyListHead
  8. tempNode = tempNode->next
  9. 转到第3步。
  10. 为节点newCopyNode分配内存。
  11. tempNode->data复制到newCopyNode->data
  12. newCopyNode->next设置为NULL。
  13. copyListTempNode->next指向newCopyNode
  14. copyListTempNode = newCopyNode
  15. tempNode = tempNode->next
  16. 转到第3步。
  17. 停止。

答案 1 :(得分:1)

没有递归===使用迭代。 P-代码:

LinkedList *l1 = (the_head), *l2 = copy_node(l1);
for (tmp l1->next; tmp != NULL; tmp = tmp->next, l2 = l2->next) {
    l2->next = copy_node(tmp);
}

答案 2 :(得分:1)

如何运作

  1. 声明两个指针:一个dst指针,它将是最终的函数结果,而next指向指针,它始终包含地址将接收下一个节点分配的指针。 next指向指针的指针最初保存dst的地址。

  2. 虽然我们仍然有要复制的节点(src != NULL),但请执行以下操作:

    • 分配新节点,将结果指针指定给*next
    • 将节点数据从src复制到*next
    • 指定next以保留我们刚刚分配的node->next成员的地址。该成员可以使用&(*next)->next获得。
    • 将输入源指针前进到下一个节点:src = src->next
    • 重复(2)。
  3. 完成后,始终*next NULL的值。这可确保添加到列表中的最终节点(如果有)具有NULL指针的next。如果根本没有节点添加到列表中(例如,当调用我们的函数时srcNULL时),则会将dst的值设置为NULL,因为它是dst中当前持有的next的地址。

  4. 返回dst的值作为函数结果。

  5. 此算法的代码如下所示:

    typedef struct Node
    {
        int data;
        struct Node *next;
    } Node;
    
    Node* CopyList(const Node* src)
    {
        Node *dst = NULL, **next = &dst;
        while (src)
        {
            // allocate new node
            *next = malloc(sizeof(**next));
            if (*next)
            {
                // copy_node() for complex duplication
                (*next)->data = src->data; 
    
                // reposition our next-link to the address of ptr->next
                //  of the node we just added.
                next = &(*next)->next;
    
                // and finally, advance the source pointer
                src = src->next;
            }
            else
            {
                perror("Failed to allocate node.");
                exit(EXIT_FAILURE);
            }
        }
        *next = NULL;
        return dst;
    }
    

    注意:这也是从串行输入文件构建前向链接列表的好方法。它确保头仅初始化一次,并且每个后续节点始终固定在最后一个节点的next指针上。

答案 3 :(得分:0)

根本没有理由使用递归 - 简单的迭代非常有效。复制节点。如果指向下一个节点的指针不为null,则重复下一个节点的过程(并将刚复制的节点中的next链接设置为指向您复制的下一个节点。)

答案 4 :(得分:0)

将链表复制到空列表的简单方法是使用递归,如下所示

struct Node {
    int value;
    Node* next;
};

Node* copy_list(Node* list) {
    if (list == NULL) return NULL;

    Node* result = new Node;
    result->value = list->value;
    result->next = copy_list(list->next);
    return result;
}

但是如果你不想使用递归,那么你必须手动,通过使用循环将每个不复制到空列表,直到你得到(节点) - > next = NULL作为检查。