首页 > 解决方案 > 克隆链接列表时如何将内存分配给 tail->next 指针

问题描述

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

我不明白如何将内存分配给 tail->next 指针,以及它如何仍然指向 head_copy 指针。尾=尾->下一个;现在tail指向使用malloc分配给它的新内存,但它仍然指向head_copy。

谁能帮我理解这段代码的流程。

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; 
}

标签: clinked-listcopysingly-linked-list

解决方案


在 while 循环的第一次迭代中,指针head_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_copytail由于这个赋值,指针也指向同一个节点

tail = head_copy;

在循环的第二次迭代中,指针head_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_copytail彼此相等。然后tail被重新赋值为tail->next

tail = tail->next;

tail现在指向已创建列表的当前最后一个节点。所以从这里开始,指针tail永远不会等于存储在指针中的值head_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;
}

推荐阅读