我已经创建了双重链表,我设法将它从头到尾打印出来,但是我无法向后执行。我得到分段错误" 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;
}
但是,我仍然不明白为什么我的方法不起作用。如果有人能解释一下,我会感激不尽。
答案 0 :(得分:4)
当您完成向前移动循环时,current
将设置为NULL
,因此请使用以下行:
current = current->prev;
不会很好地结束。您不能取消引用NULL
。
您的第二个代码段工作的原因是:
current = head;
while (current->next) current = current->next;
它使current
指向列表中的 last 项而不是NULL
。
大多数双向链接列表往往同时具有head
和 a tail
,您可以使用后者进行反向扫描。
如果您没有拥有tail
,那么第二个代码段可能似乎就像找到结束的可接受方式一样,但效率较低 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;
}
答案 1 :(得分:1)
第一次向前遍历列表以打印它的元素时,循环在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;
}
请注意,在您的修复中,您基本上就是这样做的。