在双链表中搜索和删除

时间:2013-11-25 21:29:27

标签: c++ list linked-list delete-operator

我想在双链表中搜索并删除它。

我的问题是我丢失了之前和我要删除的节点的节点。

这是我的代码:

    int delnode(string moviename)
        {
            node *temp,*del;
            //check empty
            if(!head)
                {
                    cout<<"empty";
                }
            else
                {
                    temp=head;
                while (temp->next!=NULL)
                    {

                        if (temp->title==moviename)
                            {
                                del=temp;
                                temp=temp->previous;
                                temp->next=del->next;
                                delete del;
                            }
                        temp=temp->next;
                    }
                }
        }

例如,如果我有5部电影,movie1,movie2,movie3,movie4,movie5并想要删除movie3,我的列表将是movie1,movie4,movie5:S

4 个答案:

答案 0 :(得分:3)

你在自己身上做得非常难。您的代码存在许多问题,包括:

  • 未能正确连接上一个指针
  • 未能考虑最后一个节点的删除。
  • 如果是潜在客户节点,则无法推进头指针。

考虑到这一点,我认为这可以满足您的需求,并且我强烈建议您仔细检查它,甚至在调试器中单步检查它是如何工作的。

void delnode(const std::string& moviename)
{
    // pp holds the address of the pointer that will
    //  eventually point to our node being deleted.
    node **pp = &head;

    // skip nodes until we find a match
    while (*pp && (*pp)->title.compare(moviename))
        pp = &(*pp)->next;

    if (*pp)
    {
        node *tmp = *pp;
        if ((*pp = tmp->next)) // assignment-eval intentional
            (*pp)->previous = tmp->previous;
        delete tmp;
    }
}

这解决了许多问题,包括

  • 正确更新头部指针,如果它是与您的字符串匹配的节点。
  • 正确地将nextprevious连接到所有正确的指针
  • 正确删除列表中的 last 节点(如果这是您的可疑节点)。
  • 如果头指针为空,则绝对不做任何事。

答案 1 :(得分:0)

您没有在最后的previous更新temp->next链接。

您需要在temp->next->previous = temp行之前添加delete del,因为您使用的是双重链接列表。

答案 2 :(得分:0)

你有几个问题。

如果您的列表只有一个项目,那么您将永远不会因为

而对其进行测试
if ( temp->next != NULL )

如果您的项目位于要删除的列表的开头,则不会更新头部,并且您的代码将无论如何都会崩溃,因为您没有测试temp-&gt; previous是有效的。

如果删除某个项目,则不会将后指针更新为@Leigh提及。

这是我从列表模板中取消链接项目代码:

void    untie_pointer( _Tp * aptr )
{
    if ( aptr )
    {
        if ( aptr-> prior() ) { aptr-> prev_-> next_= aptr-> next_ ; }
            else { if ( first_ == aptr ) { first_= aptr-> next_ ;  if (first_) { first_-> pr
ev_= nullptr ; } } }
        aptr -> prev_= nullptr ;
        if ( aptr-> next() ) { aptr-> next_-> prev_= aptr-> prev_ ; }
            else { if ( last_ == aptr ) { last_= aptr-> prev_ ;  if ( last_ ) { last_-> next
_= nullptr ; } } }
        aptr-> next_= nullptr ;
    }
}

由于所有这些情况,gcc stl列表使用了一个sentinel对象。

答案 3 :(得分:0)

这是我编写的用于检查节点

的代码

1.在前面,后面没有节点。

2.位于前面,后面有节点。

3.节点是最后一个节点

4.a节点位于第n个位置

      private void button1_Click_3(object sender, EventArgs e)
    {
        OpenFileDialog OutputFilePath = new OpenFileDialog();

        string OutputString = OutputFilePath.FileName;
        FilePathBox.Text = OutputString;

    }