此函数应该从链表中删除元素。目前它正在完成这项工作,但通过进一步的测试,我发现在使用该功能约2-3次后出现分段错误。例如,假设listA
包含1 2 3 4 4 5
,当我执行remove listA 4
然后打印listA
的元素时,输出应为1 2 3 5
,它是。但是当我在列表中多次使用删除功能1-2时,它就会停止工作并且我不断收到分段错误。我不知道为什么..任何帮助将不胜感激!
void mylist::remove(int z)
{
Node *currP, *prevP;
prevP = NULL;
for (currP = head;
currP != NULL;
prevP = currP, currP = currP->next) {
if (currP->key == z) {
if (prevP == NULL) {
head = currP->next;
} else{
prevP->next = currP->next;
}
delete currP;
currP=prevP;
numberofnodes--;
}
}
return;
}
答案 0 :(得分:2)
删除第一个节点表单列表时,您没有处理这种情况,因为prevP
将为空。删除currP
后,您将分配currP=prevP;
。在下一次迭代中,当prevP = currP, currP = currP->next
执行下一次for循环迭代时,将导致分段错误。
您可以使用while循环,例如:
void mylist::remove(int z)
{
Node *currP, *prevP, *temp;
prevP = NULL;
currP = head;
while(currP != NULL){
if (currP->key == z) {
if (prevP == NULL) {
head = currP->next;
} else{
prevP->next = currP->next;
}
temp = currP;
currP = currP->next;
delete temp;
numberofnodes--;
}
else
{
prevP = currP;
currP = currP->next;
}
}
return;
}
答案 1 :(得分:1)
考虑删除列表中的第一个条目时会发生什么:您设置了head = currP->next
,但将prevP
保留为NULL
。当代码到达currP=prevP
时,currP
变为NULL
,然后您将尝试在迭代中访问currP->next
时出错。您需要重新组织循环以避免这种情况。
答案 2 :(得分:1)
在for-loop上移动到下一次迭代时,指针管理是不正确的。在删除第一个项目时将currP
设置为NULL时,您将在for循环的迭代增量步骤中取消引用NULL。
老实说,for循环首先不是这个算法最热门的想法,但是如果你真的想用最少的努力来做这个,指针到指针的解决方案可以简化这个任务:
void mylist::remove(int z)
{
Node **pp = &head;
while (*pp)
{
if ((*pp)->key != z)
{
pp = &(*pp)->next;
}
else
{
Node *victim = *pp;
*pp = victim->next;
delete victim;
--numberofnodes;
}
}
}
如何运作
指向指针pp
的指针保存了我们有兴趣检查匹配的指针的地址。这最初保存head
指针的地址。
Node **pp = &head;
对于每个不匹配,我们移动到当前节点的next
指针的地址:
if ((*pp)->key != z)
{
pp = &(*pp)->next;
}
但是,当我们发现匹配时,pp
中保存地址的指针值会保存到临时:
Node *victim = *pp;
然后那个指针(如果这是列表中的第一项,它可能是head
指针)被更新为其指向节点的next
指针值。
*pp = victim->next;
最后,丢弃现在未链接的节点。
delete victim;
注意:
当我们放弃匹配时,next
有 NO 移动。我们已经通过在删除之前加载*pp
并在其自己的next
指针中保存指针值来移动到那里。此外,(希望很明显) critical 如果列表为空,则head
指针为NULL,并且最后一个节点next
指针为NULL
以终止列表。我知道标准链表的东西,但它很重要,因此提到了。
祝你好运。
答案 3 :(得分:1)
考虑删除列表中的1。 prevP = NULL; 然后你删除currP并用prevP分配它,女巫是NULL。 这个循环的结束。 然后它转到以下部分:prevP = currP,currP = currP-> next; 后一种情况的问题,因为currP是NULL。您正在访问NULL-> next。
答案 4 :(得分:0)
删除currP; currP = prevP;
这导致分段错误,在第一次迭代时,prevP为null,因此如果在迭代情况下执行prevP不是Null。