【问题标题】:How would I make a copy of a linked list using an ADT in C?如何使用 C 中的 ADT 制作链表的副本?
【发布时间】:2020-06-27 03:06:36
【问题描述】:

所以我得到了以下结构:

typedef struct nodeStruct
{
    int data;
    struct nodeStruct *next;
}Node;

typedef struct linkedList
{
    Node *head, *tail;
}List;

我必须创建一个函数,使用给定的函数原型将现有列表的内容复制到新列表中:

List *copyList(List *passedList);

我该怎么做呢?它让我感到窒息。

编辑:如果有帮助,我有这个函数来创建一个空列表:

List *createList()
{
    List *newList = (List *)malloc(sizeof(List));

    if (newList == NULL)
    {
        puts("ERROR: Could not allocate memory\n");
        return NULL;
    }

    newList->head = newList->tail = NULL;
    return newList;
}

Edit x2:我有一个 createNode 函数和一个 insertAtTail (append) 函数,如下所示:

Node *createNode(int nodeValue) // this function creates a node with the value that is passed to it
{
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode -> data = nodeValue;
    newNode -> next = NULL;
    return newNode;
}

int insertAtTail(int nodeValue, List *passedList)
{
    Node *newNode = (Node *)malloc(sizeof(Node));

    if (newNode == NULL)
    {
        puts("ERROR: Could not allocate memory.\n");
        return -1;
    }

    newNode -> data = nodeValue;
    newNode -> next = NULL;

    if (passedList->tail == NULL)
    {
        passedList->head = passedList->tail = newNode;
    }
    else
    {
        passedList->tail->next = newNode;
        passedList->tail = newNode;
    }
    return 1;
}

提前致谢!

【问题讨论】:

  • 我假设您遍历列表以在途中复制并建立列表的副本。
  • @Thomas 我不太确定如何使用linkedList 结构来做到这一点。如果只是 nodeStruct 会简单得多,但这让我更难理解。
  • 你有在列表末尾添加元素的功能吗?如果没有,写一个?然后,当您逐步浏览旧列表时,您使用该函数将旧列表中当前节点的副本添加到新列表的尾部。理想情况下,您有一个函数可以将函数“应用”到列表的每个元素,但这是为将来准备的——现在,编写代码以或多或少地复制列表。
  • "So I am given the following structs:" -- 感谢您的教授知道他在做什么。在您的函数中,只需声明一个新指针来表示您复制的列表,然后遍历当前列表,调用 add 节点函数将当前列表中的每个节点添加到副本中,请参见 add() in ,例如Singly Linked List of Integers。然后只需返回指向副本的指针。
  • 另一个想法是,由于您的 list (包装器)仅包含 head/tail 指针,因此您实际上不需要为列表分配。只需将您的返回类型更改为 List 并使用 自动存储持续时间 声明您的副本并返回结构(保存分配并释放 List - 您只需要担心释放Node列表中的节点)

标签: c algorithm linked-list


【解决方案1】:

您可以将其分解为任务:

  1. 创建一个新节点。
  2. 遍历旧列表。
  3. 将节点添加到新列表中。

所以创建一个名为createNode() 的函数,它像createList() 一样向调用者返回一个新节点。

然后创建一个名为appendList()(或您喜欢的任何名称)的函数,它将单个节点添加到链表的末尾。此函数应使用createNode() 来创建新节点。它还应该能够处理将节点添加到空链表。

然后在copyList() 中,创建一个新列表(您将复制值到的列表),遍历旧链表并调用appendList() 函数将节点值放入新列表中。然后返回一个指向新列表的指针。

【讨论】:

  • 我已经用我的createNodeinsertAtTail 函数更新了我的帖子。现在已经完成了,我只需要帮助为函数布置正确的代码。我将如何使用 ADT 遍历旧列表?这是我正在努力解决的一件事。
  • 您可以使用 while 循环来测试当前的迭代指针是否不为空,如果为空,您可以将节点值附加到新列表并转到其下一个节点。您从传递的列表的头指针开始。
猜你喜欢
  • 2016-01-29
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 2014-06-11
  • 1970-01-01
  • 2013-04-22
  • 2021-10-23
  • 2013-05-17
相关资源
最近更新 更多