C 插入两个元素后,循环链表只有一个元素

C 插入两个元素后,循环链表只有一个元素,c,linked-list,circular-list,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 * i

我正在尝试实现一个循环链表,但它并没有像我预期的那样工作。即使我用
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);
}
#包括
#包括
#包括
结构dnode_elm{
国际项目;
结构dnode_elm*下一个,上一个;
};
结构dnode_elm*
insertAfter(结构dnode_elm*a,int值){
struct dnode_elm*v=malloc(sizeof(struct dnode_elm));
v->item=值;
a->next=v;
v->prev=a;
v->next=a->next;
a->next->prev=v;
返回v;
}
无效的
打印列表(结构dnode_elm*h){
while(h!=h->next){
h=h->next;
printf(“%d-->”,h->item);
}
}
int
主(空){
结构dnode_elm h={INT_MAX,&h,&h};
插入后(&h,1);
插入后面(&h,2);
打印列表(&h);
}

您的插入逻辑错误

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;
举例说明:


a
之后插入
v


设置
v->next
v->prev


设置
v->next->prev
v->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);
}

您的插入逻辑错误

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;
举例说明:


a
之后插入
v


设置
v->next
v->prev


设置
v->next->prev
v->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);
}

此外,在启用警告并将其设置为错误的情况下进行编译
gcc-Wall-Werror
例如。另外,请给出一个简单的示例,添加实际的函数调用来演示问题,现在我们只需要理解韩语,并猜测您要输入什么来重现问题。@AnttiHaapalaI添加了,但仍然不起作用。。。只有虚拟节点被打印出来。如果没有
#include
malloc
可以在许多平台上中断,因为假定它隐式返回
int
,而不是指针。它似乎可以工作,但当指针不适合int时会中断。此外,在编译时启用警告并将其设置为错误
gcc-Wall-Werror
例如。另外,请给出一个简单的示例,添加实际的函数调用来演示问题,现在我们只需要理解韩语,并猜测您要输入什么来重现问题。@AnttiHaapalaI添加了,但仍然不起作用。。。只有虚拟节点被打印出来。如果没有
#include
malloc
可以在许多平台上中断,因为假定它隐式返回
int
,而不是指针。它似乎可以工作,但当指针不适合int时会中断。@jxhwhy v->next->prev=v;v->prev->next=v@JoJay将下一个和上一个节点设置为指向
v
。(人们可以在那里使用
a
来表示
v->prev
,但这样写更明显)。@jxhI将变量设置为无效双指针,似乎有效。但是,当循环运行infinatelylike 2147483647-->90-->2147483647-->90-->2147483647-->90-->2147483647时……@JoJay:Fix
printList
@jxhwhy v->next->prev=v;v->prev->next=v@JoJay将下一个和上一个节点设置为指向
v
。(人们可以在那里使用
a
来表示
v->prev
,但这样写更明显)。@jxhI将变量设置为无效双指针,似乎有效。但是,当循环运行infinatelylike 2147483647-->90-->2147483647-->90-->2147483647-->90-->2147483647-->90-->2147483647时……@JoJay:Fix
printList