圆形链表在插入两个后只有一个元素

时间:2016-05-14 07:36:41

标签: c linked-list circular-list

我正在尝试实现循环链​​表,但它没有按预期工作。即使我使用insertAfter插入两个元素,printList也只打印一个节点。这是一个最小的例子:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

struct dnode_elm {
    int item;
    struct dnode_elm *next, *prev;
};

struct dnode_elm *
insertAfter(struct dnode_elm *a, int value) {
    struct dnode_elm *v= malloc(sizeof(struct dnode_elm));
    v->item=value;
    a->next=v;
    v->prev=a;
    v->next=a->next;
    a->next->prev=v;
    return v;
}

void
printList(struct dnode_elm *h) {
    while (h != h->next) {
        h = h->next;
        printf("%d --> ",h->item);
    }
}

int
main(void) {
    struct dnode_elm h = { INT_MAX, &h, &h };
    insertAfter(&h, 1);
    insertAfter(&h, 2);
    printList(&h);
}

1 个答案:

答案 0 :(得分:7)

您的插入逻辑错误。

a->next=v;
v->prev=a;
v->next=a->next;
a->next->prev=v;

在这段代码之后,v->next等于v,这可能不是您想要的。

一种可能的解决方法是首先分配v的指针,然后在v之后修复节点。

v->prev = a;
v->next = a->next;
v->next->prev = v;
v->prev->next = v;

举例说明:

enter image description herev之后插入a

enter image description here设置v->nextv->prev

enter image description here设置v->next->prevv->prev->next

但是,您也可以通过将第一个作业移动到最后一个作业来重新安排代码中的作业。

v->prev=a;
v->next=a->next;
a->next->prev=v;
a->next=v;

这允许a->next->prev的分配按预期工作。

此外,您的打印逻辑存在缺陷。您需要记住初始列表指针是什么,这样您就可以正确地检测到何时到达终点。

void *start = h;
while (start != h->next) {
    h = h->next;
    printf("%d --> ",h->item);
}