从单链接和双链接列表中删除随机节点

时间:2011-11-30 20:53:28

标签: c linked-list singly-linked-list doubly-linked-list

我很难想出从双向和单链表中删除某个节点的逻辑。我从帮助中看到了在线,但我找不到一个简单的例子。这就是我所拥有的:


双重链接删除。 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;
}

问题是,在我从两个列表中删除一组随机节点后,双向链表从头到尾正确显示,但不是从头到尾。单链表也无法正确显示。

2 个答案:

答案 0 :(得分:3)

你的双链表逻辑看起来很好。我唯一担心的是,如果dCurrent是列表中唯一的元素,那么:

if (dCurrent == dHead){
    dHead = dCurrent->next;
    dHead->prev = NULL;
}

很可能会尝试引用空指针。 (这取决于您如何设计列表。但在典型设计中,如果dCurrent是唯一的节点,则dCurrent->nextNULL。)

假设“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以保持一致性。