函数多次不工作

function not working multiple times?

本文关键字:工作 函数      更新时间:2023-10-16

这个函数应该从链表中删除元素。然而,目前它已经完成了这项工作,经过进一步的测试,我发现在使用该函数约2-3次后,我出现了分割错误。例如,假设listA包含1 2 3 4 4 5,当我执行remove listA 4,然后打印listA的元素时,输出应该是1 2 3 5,事实确实如此。但是,当我在列表上再使用1-2次remove函数时,它就停止了工作,并且不断出现分段错误。我不知道为什么。。任何帮助都将不胜感激!

  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;
         }

当第一个节点表单列表被删除时,您不会处理这种情况,因为prevP将为null。删除currP之后,您正在分配currP=prevP;。在下一次迭代中,当执行prevP = currP, currP = currP->next进行下一次循环迭代时,将导致分割故障。

你可以使用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;
     }

考虑当您删除列表中的第一个条目时会发生什么:您设置了head = currP->next,但将prevP保留为NULL。当代码到达currP=prevP时,currP变为NULL,然后在迭代中尝试访问currP->next时会遇到错误。你需要重新组织你的循环来避免这种情况。

在for循环上移动到下一次迭代时的指针管理是不正确的。当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;

注意:

当我们放弃匹配时,nextNO移动。在删除之前,我们已经通过加载*pp并将指针值保存在它自己的next指针中来移动到那里。此外,如果列表为空,则head指针为NULL,并且最后一个节点next指针为终止列表的NULL,这是(希望很明显)关键。我知道标准链接列表的东西,但它很重要,因此被提及。

祝你好运。

考虑删除列表中的1。prevP=空;然后删除currP并为其分配prevP,切换为NULL。循环结束。然后它转到的部分:prevP=currP,currP=currP->next;后一种情况是问题,因为currP为NULL。您正在访问NULL->next。

删除currP;currP=prevP;

这导致了分段错误,在第一次迭代时,prevP为null,因此如果在迭代prevP不为null的情况下执行。