我编写了以下代码来删除双向链表的开头和结尾处的节点....但这些函数的执行在两者之间停止,程序被中止......
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
答案 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)
我对这段代码摘录感到有点困惑,但我会假设这是完整的摘录......
函数deletebeg
和deleteend
不会在类定义中的任何位置声明,只能在它之后声明。通常,它看起来像:
class List{
void aFunction(List * argument);
};
void List::aFunction(List * argument){
do something
};
但除此之外,不要制作自己的链表,它会更快,并且会使用std::list<int>
(使用您列出的任何数据类型替换int)来使您的生活更轻松。
这有很多原因,但主要的原因是你不必编写它,但你也不必调试它。例如,您创建的链接列表实现使用递归函数来删除自身(当函数调用自身时,它是递归的)。如果链表非常大,这可能会导致堆栈溢出,这是由于在函数内调用了太多函数引起的。这样的事情是追踪和发现的噩梦,并使您分心于编程的真实原因。这是假设原因不是制作链表。 :P
答案 2 :(得分:0)
虽然通常不会在C ++中看到在类外声明的函数,但这并非不可能。但这意味着head1是一个未显示的全局变量。
你遗漏了部分实际上正在调用deletebeg
和deleteend
所以很难确切地说出发生了什么。也许你在删除它后使用指针。
此外,虽然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
。