当前位置: 首页 > 知识库问答 >
问题:

克隆链接列表时如何将内存分配给尾部->下一个指针

况嘉运
2023-03-14

下面是复制链接列表的工作函数,只需将原始链接列表的地址传递给此函数,它将创建一个副本并返回头部。

我不明白记忆是如何分配给尾巴的-

有人能帮我理解这段代码的流程吗。

struct node
{
    int data;
    struct node* next; //Pointing back to the same structure.
};

struct node* copy_link_list(struct node** head)
{
    struct node* head_copy = NULL;
    struct node* tail = NULL;

    while (*head != NULL)
    {
        //printf("data in copy is %d and local_variable addr is %p\n",temp->data,&local);
        if (head_copy == NULL)
        {
            head_copy = malloc(sizeof(struct node));
            head_copy->data = (*head)->data;
            head_copy->next = NULL;
            tail = head_copy;
        }
        else
        {
            //printf("1. tail /// tail_of_data /// tail_of_next %p %d %p\n",&tail,tail->data,&(tail->next));
            printf("head_copy head_copy_of_data and head_copy_of_next %p %d %p\n",&head_copy,head_copy->data,(head_copy->next));
            tail->next = malloc(sizeof(struct node));
            printf("2. tail /// tail_of_data /// tail_of_next %p %d %p %p\n",&tail,tail->data,&(tail->next),tail->next);
            tail = tail->next;
            printf("3. tail /// tail_of_data /// tail_of_next %p %d %p %p\n",&tail,tail->data,&(tail->next),tail->next);
            tail->data = (*head)->data;
            tail->next = NULL;
        }
        *head = (*head)->next;
    }

    return head_copy; 
}

共有1个答案

葛承德
2023-03-14

在while循环的第一次迭代中,指针head\u copy等于NULL。所以执行这个if语句。

    if (head_copy == NULL)
    {
        head_copy = malloc(sizeof(struct node));
        head_copy->data = (*head)->data;
        head_copy->next = NULL;
        tail = head_copy;
    }

现在,节点的内存已分配,其地址已分配给指针head\u copy。由于该赋值,指针tail也指向同一节点

tail = head_copy;

在循环的第二次迭代中,指针head\u copy已经不等于NULL。因此执行else语句。

    else
    {
        //printf("1. tail /// tail_of_data /// tail_of_next %p %d %p\n",&tail,tail->data,&(tail->next));
        printf("head_copy head_copy_of_data and head_copy_of_next %p %d %p\n",&head_copy,head_copy->data,(head_copy->next));
        tail->next = malloc(sizeof(struct node));
        printf("2. tail /// tail_of_data /// tail_of_next %p %d %p %p\n",&tail,tail->data,&(tail->next),tail->next);
        tail = tail->next;
        printf("3. tail /// tail_of_data /// tail_of_next %p %d %p %p\n",&tail,tail->data,&(tail->next),tail->next);
        tail->data = (*head)->data;
        tail->next = NULL;
    }

在else语句的开头,head\u copytail彼此相等。然后用tail的值重新分配tail-

tail = tail->next;

也就是说,tail现在指向所创建列表的当前最后一个节点。因此从这里开始,指针tail永远不等于指针head\u copy中存储的值。它指向当前创建的新节点,该节点是已创建列表的最后一个节点。

请注意,该函数可以看起来更简单。例如,不需要通过引用传递复制列表的指针头。

struct node* copy_link_list( const struct node *head )
{
    struct node *head_copy = NULL;
    struct node **tail = &head_copy;

    for ( ; head != NULL; head = head->next )
    {
        *tail = malloc( sizeof( struct node ) );

        ( *tail )->data = head->data;
        ( *tail )->next = NULL;

        tail = &( *tail )->next;
    }

    return head_copy;
}

 类似资料:
  • 我试图克隆一个循环链表,就像你克隆一个单链表一样,但是我遇到了麻烦。 我试图在公共方法clone()中只留下调用clone()的受保护方法的那一行,但是程序仍然抛出错误。 } 此代码在使用单个链接列表时有效。预期的输出是打印两次的链接列表,但实际的输出是抛出的异常“CloneNotSupported”。请注意,当clone()返回空列表时,程序不会抛出此异常。

  • 我目前正在为Java中的循环链表工作。我们应该能够在列表的前面插入和后面插入。但是,我已经让这些方法在循环链表类中正常工作。 我得到的结果是 对于第二次插入,这里的next指向null应该指向列表的头部。 节点类 循环链表类 主班

  • 问题内容: 如果我有:和 如果调用,我是否可以通过这种方式将linkedlist2附加到linkedlist1的末尾: 它变为并 变为? 那可能吗 ?还是我需要其他结构? 以下代码不起作用: 输出: 问题答案: Java提供的标准LinkedList类缺少此功能。 正如Donal Boyle所发布的那样,您可以将一个列表的内容添加到另一个列表中,但这并不能像您所描述的那样保持链接。

  • 问题内容: 如何克隆 Java并同时在Java中克隆其项目? 例如,我有: 我希望其中的对象与狗列表中的对象不同。 问题答案: 你将需要迭代这些项目,然后逐个克隆它们,然后将克隆放入结果数组中。 显然,要使该方法起作用,你将必须使你的类实现接口并重写该方法。

  • 似乎人们总是说,如果一个单链接列表的头是空的,那么这个列表是空的,但是检查尾部也会起作用吗?假设我确实知道一个列表有一个尾部,我可以检查尾部是否为空以确定它是否为空吗?

  • 问题内容: 我正在研究数据结构和链表,但是我没有得到如何制作链表副本的概念。有人可以使用伪代码或C代码进行解释吗? 问题答案: 复制链表的逻辑是递归的,并且基于以下观察结果: 空列表的克隆是空列表。 具有第一个节点x和其余节点xs的列表的克隆是x的副本,该副本位于xs的克隆之前。 如果您使用C ++对链表进行编码,则可以很干净: