从链表中删除元素后显示时,显示0代替删除的元素。我无法更新节点。任何人都可以解释发生了什么?为什么显示0?
#include<iostream>
#include<stdlib.h>
using namespace std;
class node {
public:
int data;
node *link;
};
class linkedlist {
node *head;
public:
linkedlist() {
head=NULL;
}
int add(int data1) {
node *insertnode=new node;
insertnode->data=data1;
insertnode->link=NULL;
node *temp=head;
if(temp!=NULL)
{
while(temp->link!=NULL)
{
temp=temp->link;
}
temp->link=insertnode;
}
else{head=insertnode;}
}
void disp()
{
node *temp1=head;
cout<<endl;
if(temp1==NULL)
{
cout<<"Empty"<<endl;
}
if(temp1->link==NULL)
{
cout<<temp1->data<<endl;
}
else {
do {
cout<<temp1->data<<endl;
temp1=temp1->link;
} while(temp1!=NULL);
}
}
int remove(int removedata)
{
node *previous;
node *temp2=head;
if(temp2==NULL)
{exit(0);}
if(temp2->link==NULL)
{
delete temp2;
head=NULL;
}
else
{
while(temp2!=NULL)
{
if(temp2->data==removedata)
{
previous=temp2;
delete temp2;
}
temp2=temp2->link;
}
}
}
};
int main()
{
linkedlist list;
list.add(10);
list.add(100);
list.add(200);
list.remove(10);
list.disp();
}
显示的输出是:
0
100
200
答案 0 :(得分:1)
您已删除了头节点,但如果发生这种情况,代码中的任何内容都不会重新分配头节点。
所以你在这里有未定义的行为。
您也这样做:
if(temp2->data==removedata)
{
previous=temp2;
delete temp2;
}
temp2=temp2->link;
换句话说,你删除了一些东西,然后取消引用它。我不确定previous
应该在这里做什么,但也现在包含指向已被删除的内容的指针。幸运的是,这似乎是它唯一引用的地方(这里的目的是什么?)
你的函数似乎没有返回任何东西,但它被声明为返回一个int。
所以我觉得这里的逻辑都是错的。
您需要做的是:
像这样(未经测试):
if(head == NULL) return; // List is empty.
node *prev = head;
if(prev->data == removedata)
{
head = prev->link;
delete prev;
return; // removed the head node
}
while(prev->link)
{
if(prev->link->data == removedata)
{
node *t = prev->link;
prev->link = t->link;
delete t;
return; // removed a non-head node
}
prev = prev->link;
}
// data is not in the list
或者如果你想尝试聪明并消除特殊情况:
node **prevptr = &head;
node *cur = head;
while(cur)
{
if(cur->data == removedata)
{
*prevptr = cur->link;
delete cur;
break;
}
prevptr = &cur->link;
cur = cur->link;
}
答案 1 :(得分:1)
我可以建议我的代码吗?
int removeData(int target)
{
//Let's return -1 if we can't find the target element.
node *p,*q;
for(q=head;q!=NULL && q->data!=target;p=q,q=q->link)
;
if(q==NULL)
{
//Either the list was empty or the target element was not on the list
return -1;
}
else
{
//We found the element, let's delete it.
int ret=q->data;
if(q==head)//If target node is the first node in list
head=q->link;
else
p->link=q->link;
delete q;//We delete the node pointed to by q here, which is our target node
return ret;
}
}
让我解释一下上面的代码。首先我们有两个临时指针,指向前一个节点( p )和当前节点( q )我们遍历链表。只要列表没有结束或只要当前节点不是我们的目标节点,我们就会遍历列表。
当我们退出for循环时,我们可以退出两个原因。
q 都变为NULL,这可能有两个含义,要么我们的列表为空,要么我们的列表没有目标节点。所以我们返回-1,报告问题。
或者q->data
等于target,这意味着我们找到了我们的目标节点,让我们删除它。我们存储当前值并删除节点。通常会返回已删除节点的数据。希望这有帮助。
答案 2 :(得分:1)
这与this answer到your previous question密切相关。
让我们格式化这个功能,仔细看看。
int remove(int removedata)
{
node* previous; // Why is this unintialised?
node* temp2 = head; // Can you think of a more meaningful name for this
// variable? Perhaps "current"?
if (temp2 == NULL)
{
exit(0); // Do you really want to exit the program if you try to
// remove an item from an empty list? Is there a better way
// to handle this?
}
if(temp2->link == NULL) // What is so special about a linked list with one element?
{
delete temp2; // You've not checked to see if this element is
// `removedata`
head = NULL; // So calling this function for any list with one element
// results in an empty list. This is probably
// undesirable
}
else
{
while (temp2 != NULL) // Consider using a for-loop for iteration. It
// couples the increment(s) with the
// terminating condition.
{
if (temp2->data == removedata) // At this point we have found
// our candidate for removal
{
previous = temp2; // This is not the "previous" node, but
// the "current" one. And this variable is
// never used. You do need to know where
// the previous node is and whether it is
// 'head' to update either the 'link' or
// 'head'
delete temp2; // This does remove the correct node but
// leaves the previous 'link' pointer
// dangling and any subsequent nodes are
// orphaned.
}
temp2 = temp2->link; // See comment above about for-loops.
}
}
} // This function is declared `int` but has no return statement.
替代实现可能看起来像这样(未经测试):
void remove(int removedata)
{
for (node* current = head, * previous = NULL;
current;
previous = current, current = current->link)
{
if (current->data == removedata)
{
if (previous)
{
previous->link = current->link;
}
else
{
head = current->link;
}
delete current;
break;
}
}
}