合并两个链表之后的无限循环

时间:2019-03-20 11:23:33

标签: c linked-list

我有两个链接列表TargetList

      struct node
        {
            int data;
            struct node *next;
        };

        struct snode
        {
            struct node *head;
            struct node *last;
            int size;
        };
void *createlist(struct snode *list)
{
    list->head = NULL;
    list->last = NULL;
    list->size = 0;
}


struct node *createnode(int data)
{
    struct node *temp = (struct node *)malloc(sizeof(struct node));
    temp->data = data;
    temp->next = NULL;
    return temp;
}

int Add(struct snode *list, int data, int pos) 
{
    struct node *temp = createnode(data);
    if (pos == 0) // add to first node
    {
        if (list->head == NULL)
        {
            list->head = temp;
            list->last = temp;
        }
        else
        {
            temp->next = list->head;
            list->head = temp;
        }
    }
    else if (pos == -1) // add to last node
    {
        if (list->head == NULL)
            list->head = temp;
        else
        {
            struct node *pre = list->head;
            while (pre->next != NULL)
                pre = pre->next;
            pre->next = temp;
            temp->next = NULL;
        }
    }
    else // add to the middle
    {
        int k = 1;
        struct node *pre = list->head;
        while ((pre != NULL) && (k != pos))
        {
            pre = pre->next;
            k++;
        }
        if ((k != pos) || (pos > list->size))
            return 0;
        else
        {
            temp->next = pre->next;
            pre->next = temp;
        }
    }
    list->size++;
    return 1;;
}
int copy(struct snode *target, struct snode *list)
{
    struct node *temp1 = list->head;
    struct node *temp2 = createnode(temp1->data);
    target->head = temp2;
    if (temp1 == NULL)
        return 0;
    while (temp1 != NULL)
    {
        temp2->next = temp1->next;
        temp1 = temp1->next;
        temp2 = temp2->next;
        target->size++;
    }
    return 1;
}
void printlist(struct snode list)
{
    while (list.head != NULL)
    {
        printf("%2d", list.head->data);
        list.head = list.head->next;
    }
}
int main()
{
    struct snode list;
    struct snode target;
    createlist(&list);
    createlist(&target); //create empty linkedlist
    Add(&list, 4, 0); //add node to linkedlist
    Add(&list, 6, 1);
    Add(&list, 9, -1);
    Add(&list, 7, 2);
    Add(&list, 5, 3);
    copy(&target,&list); //copy list to target
    combine(&target,&list);
    printlist(target);
}

我想将TargetList连接起来,所以我使用了此功能

void combine(struct snode *target, struct snode *list)
{
    struct node *temp1=list->head;
    struct node *temp2=target->head;
    while(temp2->next!=NULL)
        temp2=temp2->next;
    temp2->next = list->head;

}

但是当我打印它时,它会产生无限循环。我尝试调试,并在此行之后看到了这一点:

temp2->next = list->head

List的最后一个节点指向List的第一个节点。

我不知道为什么会这样,有人可以告诉我为什么以及如何解决此问题吗?

1 个答案:

答案 0 :(得分:0)

我没有从您发布的代码中得到无限循环,但是我可以很容易地看到这种情况如何发生。问题是复制和合并的结合:复制使目标仅在头部不同,但是之后的所有节点与列表中的节点完全相同。因此,当您在合并中遍历目标时,然后将最后一个节点的位置设置为列表头的旁边,就创建了一个循环。

我不确定您的意图是什么,但是解决此问题的一种方法是仅将节点数据复制到副本中,而不是整个节点指针。