【问题标题】:Removing a random node from both singly- and doubly-linked lists从单链表和双链表中删除随机节点
【发布时间】:2012-01-10 02:14:17
【问题描述】:

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


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

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

【问题讨论】:

  • 那么你的问题是什么。乍一看,代码没问题。
  • 代码看起来没问题。你的问题是?
  • 对不起,我忘了说明我的问题。现已修复
  • @MichaelSchilling:您显示的代码似乎不包含该错误。我认为您需要发布一个尽可能简短的完整程序,同时仍然显示您的问题。 (此外,您可能希望将此问题限制为一个问题或其他问题。双链表程序的问题可能与单链表程序的问题完全无关,在这种情况下它们应该是单独的问题,或者它们可能完全一样,在这种情况下,无论如何你只需要问一个。)

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


【解决方案1】:

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

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

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

假设 "sPrev = sCurrent->prev"; 在我看来,您的单链表逻辑在抽象上也很好。但我不明白这个假设怎么可能是正确的。如果它是一个单链表,那么sCurrent 没有prev 指针。

【讨论】:

  • sPrev 的事情是在 for 循环中处理的,只是为了避免冗长的解释
【解决方案2】:

我能看到的唯一问题是您的代码在 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。

【讨论】:

    猜你喜欢
    • 2015-04-15
    • 1970-01-01
    • 2013-10-14
    • 2010-12-26
    • 2020-02-04
    相关资源
    最近更新 更多