双链表及其删除

时间:2011-08-23 19:24:02

标签: c++ data-structures linked-list

我编写了以下代码来删除双向链表的开头和结尾处的节点....但这些函数的执行在两者之间停止,程序被中止......

struct nodeb
{
    int value;
    nodeb *next;
    nodeb *pre;   //pre of first node and next of last node point to null...
    nodeb(int a,nodeb *ptr1=0, nodeb *ptr2=0):value(a), next(ptr1), pre(ptr2)
    {}
};

class doublelist
{
private:

nodeb *head1,*head2;

public:

doublelist():head1(0),head2(0)
  {cout<<"double list created"<<endl;}


void deletebeg()//delete beginning node
{
    if(head1->next==0)
    {
        nodeb *ptr=head1;
        head1=head2=0;
        delete ptr;
    }
    else 
    {
        nodeb *ptr=head1->next;
        nodeb *ptr1=head1;
        ptr->pre=0;
        head1=ptr;
        delete ptr1;
    }
}


void deleteend()//delete end node
{
    nodeb *ptr=head1;
    nodeb *ptr1;
    while(ptr->next!=0)
    {
        ptr1=ptr;
        ptr=ptr->next;
    } 

    delete ptr;
    ptr1->next=0;
}
};  //class ends here


int main()
{
    doublelist list1;
nodeb node(8);
nodeb node1(7);
nodeb node2(9);
nodeb node3(4);
list1.insertbeg(node);
list1.insertbeg(node1);
    list1.insertafter(node3,1);
list1.insertend(node2);  //insertbeg,insertafter and insertend are three functions i defined to        attach nodes at the beginning,at a particular location and at  the end of the list 
list1.deletebeg();
} 

任何人都可以告诉我这个问题吗?this is the link to the three functions for insertions

4 个答案:

答案 0 :(得分:2)

现在我可以看到问题非常简单的所有代码。您的deletebeg函数正在使用delete删除开始节点,但您没有使用new分配节点。如果您使用delete创建内存,则应该new内存。

通常,当人们编写链表列表时,他们会使用new在列表方法中分配节点。然后他们可以安全delete方法内的节点。你正在删除,但你没有使用新的。所以你需要像这样重写你的主要功能

int main()
{
    doublelist list1;
    list1.insertbeg(8); // add 8 to beginning of list
    list1.insertbeg(7); // add 7 to beginning of list
    list1.insertafter(4,1); // add 4 after first item of list
    list1.insertend(9); // add 9 to end of list
    list1.deletebeg();
} 

然后你需要像这样重写你的方法

void insertbeg(int value)//insert beginning
{
    nodeb* a = new nodeb(value); // allocate node inside of method using new
    if(head1==0)
    {
        head1=a;
        head2=a;
        a->next=0;
        a->pre=0;
    }
    else
    {
        nodeb *ptr=head1;
        ptr->pre=a;
        a->pre=0;
        a->next=ptr;
        head1=a;
    }
}

我只显示了insertbeg,你需要以同样的方式更改所有插入方法。

我不承诺这是唯一的问题,但是做出这个改变,你就会走上正确的道路。如果您遇到更多问题,请重新发布,但请记住发布完整代码。这是你得到这样的问题的唯一方法。

答案 1 :(得分:0)

我对这段代码摘录感到有点困惑,但我会假设这是完整的摘录......

函数deletebegdeleteend不会在类定义中的任何位置声明,只能在它之后声明。通常,它看起来像:

class List{
    void aFunction(List * argument);
};  

void List::aFunction(List * argument){
    do something
};

但除此之外,不要制作自己的链表,它会更快,并且会使用std::list<int>(使用您列出的任何数据类型替换int)来使您的生活更轻松。

这有很多原因,但主要的原因是你不必编写它,但你也不必调试它。例如,您创建的链接列表实现使用递归函数来删除自身(当函数调用自身时,它是递归的)。如果链表非常大,这可能会导致堆栈溢出,这是由于在函数内调用了太多函数引起的。这样的事情是追踪和发现的噩梦,并使您分心于编程的真实原因。这是假设原因不是制作链表。 :P

答案 2 :(得分:0)

虽然通常不会在C ++中看到在类外声明的函数,但这并非不可能。但这意味着head1是一个未显示的全局变量。

你遗漏了部分实际上正在调用deletebegdeleteend所以很难确切地说出发生了什么。也许你在删除它后使用指针。

此外,虽然NULL 通常为零,但无法保证编译器的情况。你应该使用NULL而不是零。

我的猜测是你用一个节点调用deleteend,无论出于什么原因head1==0,然后ptr1从未初始化,程序在{{1}的最后一行崩溃当你试图取消引用未初始化的指针时。

答案 3 :(得分:0)

继续对我之前回答的评论

此代码错误

void insertbeg(int value)//insert beginning
{
    nodeb a(value); // create node on the stack
    if(head1==0)
    {
        head1=&a;
        head2=&a;
        a.next=0;
        a.pre=0;
    }
    else
    {
        nodeb *ptr=head1;
        ptr->pre=&a;
        a.pre=0;
        a.next=ptr;
        head1=&a;
    }
}

上面的代码会出现你所描述的问题,当你说'head1和head2将指向无处'时。但是这段代码完全不同

void insertbeg(int value)//insert beginning
{
    nodeb* a = new nodeb(value); // allocate node inside of method using new
    if(head1==0)
    {
        head1=a;
        head2=a;
        a->next=0;
        a->pre=0;
    }
    else
    {
        nodeb *ptr=head1;
        ptr->pre=a;
        a->pre=0;
        a->next=ptr;
        head1=a;
    }
}

它不同,因为它使用new来创建对象。当您使用new时,退出函数时对象不会被破坏。这就是new的含义。但是当你使用new时,你也必须在完成节点后使用delete