C 中的双向链表(打印)

Doubly linked list in C (printing)

我已经创建了双向链表,并且设法从头到尾打印它,但是我在向后打印时遇到了麻烦。我在 "current = current->prev" 行遇到分段错误,我不明白为什么。

current = head;

while (current) {
  printf("%p\t%s\t%d\n", current, current->name, current->age); 
  current = current->next;
}

current = current->prev;

while (current) {
  printf("%p\t%s\t%d\n", current, current->name, current->age); 
  current = current->prev;
}

我找到了解决这个问题的方法:

current = head;

while (current) {
  printf("%p\t%s\t%d\n", current, current->name, current->age); 
  current = current->next;
}

current = head;
while (current->next) current = current->next;

while (current) {
  printf("%p\t%s\t%d\n", current, current->name, current->age); 
  current = current->prev;
}

但是,我还是不明白为什么我的方法不起作用。如果有人能解释一下,我将不胜感激。

当你完成向前方向的循环遍历时,current 将被设置为 NULL,因此使用行:

current = current->prev;

不会有好下场。不允许取消引用 NULL.

你的第二个代码片段起作用的原因是:

current = head;
while (current->next) current = current->next;

它让 current 指向列表中的 last 项,而不是 NULL

大多数双向链表往往同时具有 head 以及 tail,您将使用后者进行反向扫描。

如果您没有tail,那么第二个代码片段可能看起来是一种可接受的查找方式最后,虽然效率不如 with a tail.

然而,它有一个致命的缺陷,那就是如果列表为空,它可能会出现错误:

current = head;                 // current <- NULL
while (current->next)           // cannot dereference NULL
    current = current->next;

像这样的东西你会过得更好:

current = head;
if (current != NULL)
    while (current->next != NULL)
        current = current->next;

如果列表为空,则将 current 设置为 NULL,否则设置为最后一项的地址。这意味着您的反向循环将正常工作:

while (current != NULL) {
    doSomethingWith (current);
    current = current->prev;
}

第一次向前遍历列表以打印其元素时,循环在 current == NULL 时结束,然后您尝试在

之后立即取消引用 current
current = current->prev;
/*          ^ NULL */

试试这个

current = head;
while (current->next) {
   printf("%p\t%s\t%d\n", current, current->name, current->age); 
   current = current->next;
}
printf("%p\t%s\t%d\n", current, current->name, current->age); 

while (current) {
   printf("%p\t%s\t%d\n", current, current->name, current->age); 
   current = current->prev;
}

请注意,在您的 修复 中,您基本上就是这样做的。