我很难想出从双向和单链表中删除某个节点的逻辑。我从帮助中看到了在线,但我找不到一个简单的例子。这就是我所拥有的:
双重链接删除。 dCurrent
是我们要删除的节点。
if (dCurrent == dHead){
dHead = dCurrent->next;
dHead->prev = NULL;
}
else if(dCurrent == dTail){
dTail = dCurrent->prev;
dTail->next = NULL;
}
else{
dCurrent->next->prev = dCurrent->prev;
dCurrent->prev->next = dCurrent->next;
}
以下是我对单链表的看法。同样,sCurrent
是要删除的节点。和sPrev = sCurrent->prev
。
if(sPrev == NULL){
sHead = sCurrent->next;
}
else{
sPrev->next = sCurrent->next;
}
问题是,在我从两个列表中删除一组随机节点后,双向链表从头到尾正确显示,但不是从头到尾。单链表也无法正确显示。
答案 0 :(得分:3)
你的双链表逻辑看起来很好。我唯一担心的是,如果dCurrent
是列表中唯一的元素,那么:
if (dCurrent == dHead){
dHead = dCurrent->next;
dHead->prev = NULL;
}
很可能会尝试引用空指针。 (这取决于您如何设计列表。但在典型设计中,如果dCurrent
是唯一的节点,则dCurrent->next
为NULL
。)
假设“sPrev = sCurrent-> prev”,你的单链表逻辑对我来说也很好看。但我不明白这个假设是如何正确的。如果它是单链接列表,则sCurrent
prev
指针。
答案 1 :(得分:0)
我能看到的唯一问题是,对于head或tail更新为NULL的情况,你的代码将无法正常运行。
基本上如果你删除唯一的节点,dHead将指向null,所以你需要在后续语句中添加“警卫”,如
dHead->prev = NULL;
喜欢这样
if (dHead != NULL) {
dHead->prev = NULL;
}
有这么多条件“绕过”的一种方法是分配一个NIL(不是一个类型)元素。
NIL是替换NULL的“节点”。它表示“关闭列表的数据部分”,因此它的下一个是ALWAYS NIL(循环引用),它的前一个是ALWAYS NIL(循环引用)。在这种情况下,您确保永远不会在列表之外访问NIL,并且head-> prev == NIL和tail-> next == NIL。这样您就可以避免使用许多if (tail != null) { ... }
类型语句。
在这样的构造下,空列表是head == NIL && tail == NIL
的列表。这大大减少了if (something == null)
语句的数量,但是你仍然需要考虑一个if语句,当head为NIL时(在删除之后)你需要将tail设置为NIL以保持一致性。