2013-11-25 166 views
1

我已经看过这个话题的其他线程,但没有能够使用它们来解决我的问题。从双向链表中删除一个节点


这是在链接列表中的节点的主类定义:

class node { 

public: 

    // default constructor 
    node() {name = ""; prev = NULL; next = NULL;}; 

    // default overloaded 
    node(string s) {name = s; prev = NULL; next = NULL;}; 

    // item in the list 
    string name; 

    // links to prev and next node in the list 
    node * next, * prev; 

}; 

以上是节点类的定义,这是在其产生链表另一类使用。链表代码给了我们,我们必须修改,所以我知道它的工作原理。我已经完成并测试了双向链表中新增节点的工作,现在我正在从这个双向链表中删除节点。

功能删除一个节点:http://pastebin.com/HAbNRM5W

^这是我需要帮助的代码中,有太多的重复键入


我被我的老师告诉记者,该代码,问题是行56,它读取:

tmp->prev = prev; 

我想设置链接到前一个节点是正确的。我尝试使用类似的if/else循环的情况是当前节点是否是列表中的最后一项。如果它是最后一项(又名curr->next = NULL),则不要使用curr->next设置链接并停止循环迭代。

任何帮助/想法/建议/反馈将不胜感激!

void linkedList::remove(string s) 
{ 
     bool found = false; 
     node * curr = getTop(), * prev = NULL; 
     node * tmp = new node(); 
     while(curr != NULL) 
     { 
       // match found, delete 
       if(curr->name == s) 
       { 
         found = true; 
         // found at top 
         if(prev == NULL) 
         { 
          node * temp = getTop(); 
          setTop(curr->next); 
          getTop()->prev = NULL; 
          delete(temp); 
         } // end if 
         else 
         { 
          // determine if last item in the list 
          if (curr->next = NULL) 
          { 
           // prev node points to next node 
           prev->next = curr->next; 
           // delete the current node 
           delete(curr); 
          } // end if 
          // if not last item in list, proceed as normal 
          else 
          { 
           // prev node points to next node 
           prev->next = curr->next; 
           // set the next node to its own name 
           tmp = prev->next; 
           // set prev-link of next node to the previous node (aka node before deleted) 
           tmp->prev = prev; 
           // delete the current node 
           delete(curr); 
          } // end else 
         } // end else 
        } // end if 

       // not found, advance pointers 
       if(!found) 
       { 
        prev = curr; 
        curr = curr->next; 
       } // end if 

       // found, exit loop 
       else curr = NULL; 
     } // end while 

     if(found) 
      cout << "Deleted " << s << endl; 
     else 
      cout << s << " Not Found "<< endl; 
} // end remove 
+0

你问的问题到底是什么? –

+0

zac,我需要此方法来删除C++中的双向链表的节点。我的讲师告诉我“tmp-> prev = prev;”是NULL,如果我修复这一行,代码/程序应该工作。我无法弄清楚什么是空/为什么它是空的,以便我可以修复它。谢谢。 – user2766542

+0

在你正在进行删除的地方,对prev,curr和curr-> next(if!null)中的每一个执行打印命名可能是一个好主意。 可以方便地分拣指针混淆。 – RichardPlunkett

回答

1

对于你的代码,我建议几件事。隔离代码以查找具有您正在查找的名称的节点。删除方法应该只删除一个双向链接的节点,只要它给出一个。

我知道你的remove方法需要一个字符串参数,但将它传递给另一个函数,并让该函数返回你正在寻找的节点。

它应该是这个样子:

Node *cur = find("abcd"); 
Node *prev = cur->prev; 
prev->next = cur->next; 

Node *n = cur->next; 
n->next = cur->prev; 

cur->next = NULL; //or nullptr 
cur->prev = NULL; //or nullptr 

delete cur; 
+0

感谢您的建议和反馈!我同意你关于你的建议,即重写方法/功能,但大纲/整个程序是由教授作为单独链接给我们的,我们必须将它转换为双重链接。通常,如果我自己在做这件事,我会以另一种方式做到这一点,但在这一点上,它会比我/我有时间去做更多的工作。 – user2766542

+0

@ user2766542 - 难道你只是添加一个私人功能?我不认为任何教授会禁止额外的私人会员。 对于您的查找函数,您应该使用for循环来自动执行搜索(使用ptr = ptr-> next迭代)。 – AFM

+0

我不知道你如何处理节点的破坏,但我假设你删除了两个指针:prev和next。如果是这种情况,您必须明确地将您要删除的节点的prev和next设置为NULL或nullptr。 这是因为如果您不这样做,您将冒险删除不仅该节点,而且删除连接到它的节点! – AFM

1

NULLnullptr

if (curr->next = NULL) { ... 

这是一个任务所取代,你想:

if (curr->next == nullptr) { ... 

在线47我想你说:如果prev == nullptr和next是不nullptr,但你使用

prev->next = curr->next; 

哪一个不行,因为prev是nullptr。

+0

非常感谢你,我将尽快研究这件事。我不知道如何改变实现,以便prev实际上是前一个节点而不是nullptr。我将立即进行nullptr更改。 – user2766542

+0

我试着将NULL改为nullptr,但是我的代码不能编译。 iostream库提供对NULL的支持,我不知道关于nullptr。 – user2766542

+0

至于你的第一个答复的最后部分:我想说,有三个节点:前一个节点,当前节点和下一个节点。如果下一个节点(curr-> next)不是nullptr,则将前一个节点指向该节点(prev-> next = curr-> next)并删除当前节点。我不知道以前定义为null/nullptr。我想这是我需要解决的问题。 – user2766542

0

应该像这样:

prev->next = curr->next; 
prev->next->prev = prev; 
delete (curr); 
+0

哇,真棒,我不知道我可以做一些像“prev-> next-> prev = prev;” – user2766542

+0

事情是,你根本不需要tmp。 你需要做2个任务,prev需要跳过curr,然后,它现在指出的东西,需要指向它。 – RichardPlunkett

+0

可选地,这第二个可以在if语句中,该检查prev-> next现在是null_ptr,并且这将减少对上面完全分离的列表结尾的需要。 – RichardPlunkett

0

我在所有不同的条件语句迷路了。所有你需要做的是:

void linkedList::remove(const std::string& s) 
{ 
    node* current = getTop(); // get head node 
    while (current != nullptr) // find the item you are trying to remove 
    { 
     if (current->name == s) 
     { 
      break; // when you find it, break out of the loop 
     } 
    } 

    if (current != nullptr) // if found, this will be non-null 
    { 
     if (current->prev) // if this is not the head node 
     { 
      current->prev->next = current->next; 
     } 
     else 
     { 
      // update head node 
     } 

     if (current->next) // if this is not the tail node 
     { 
      current->next->prev = current->prev; 
     } 
     else 
     { 
      // update tail node 
     } 

     // at this point, current is completely disconnected from the list 
     delete current; 
    } 
}