【问题标题】:Deleting a node being pointed to in a linked list [duplicate]删除链表中指向的节点[重复]
【发布时间】:2021-01-05 17:27:45
【问题描述】:

这个函数接收链表作为参数,并且必须删除链表中元素DNI与给定给get_string的字符串一致的节点,然后返回链表。目前,如果给定的节点是第一个节点,则该函数运行良好,但如果给定的节点不是第一个节点,它总是删除第一个元素并弄乱列表。我应该怎么做才能解决它?

PPACIENTE p_discharge(PPACIENTE pac){
  char dni[10];
  int u, c=0;
  PPACIENTE pAux;
  PPACIENTE temp;
  pAux=pac;
  fprintf(stdout,"Discharge\n\n");
  if (pac==NULL)
  {
    printf("No patients yet\n");
  }
  else
  {
    get_string("DNI",9,9,dni);
    while(pAux!=NULL){
      if(strcmp(pAux->DNI,dni)==0) {
        u=1;
        break;
      }
      else{
        pAux=pAux->sig;
      }
    }
    if (u==1){
      if (pAux->num==1)
      {
         pac=pAux->sig;
         free(pAux);
         return pac;
      }
      else 
      {
        printf("%d\n", pAux->num);
        c=pAux->num;
        while(pAux->num!=(c-2))
          pAux=pAux->sig;

        temp=pAux->sig;
        pAux->sig=temp->sig;
        free(temp);
      }
    }
    else{
      printf("Unknown patient\n");
    }
  }
  return pAux;
}

【问题讨论】:

  • 我不太确定u 的作用是什么,但它在到达测试if(u==1) 之前并不总是被赋值。您应该确保它从一个已知值开始,或者在测试之前总是被分配。此外,您应该尝试将其重命名为更能描述变量用途的名称。
  • 我现在看到了,@OutrageousBacon,u 是多余的。无论如何,它仅用于检查strcmp() 上的条件是否为真,所以一开始它应该始终为0。不过我认为这不是问题。
  • 我不明白你使用的字段 num 你用来做if (pAux->num==1) 但是当你删除一个单元格时,你永远不会为下一个单元格更新该字段
  • 我不知道你想用pAux->num 检查做什么。
  • has to delete the node of the list which element DNI coincides with the string given to get_string : 这不是你做的,全看pAux->num的值

标签: c linked-list singly-linked-list


【解决方案1】:

我不明白num成员的用途,所以这里就忽略了。

为了删除列表中的一个元素,你需要一个指向前一个元素的指针,如果有的话,这样前一个元素的next链接(在你的代码中称为sig)可以被更新.

PPACIENTE p_discharge(PPACIENTE pac){
  char dni[10];
  int u = 0;
  PPACIENTE pAux;
  PPACIENTE temp = NULL;  // Pointer to previous element of list
  pAux=pac;
  fprintf(stdout,"Discharge\n\n");
  if (pac==NULL)
  {
    printf("No patients yet\n");
  }
  else
  {
    get_string("DNI",9,9,dni);
    while(pAux!=NULL){
      if(strcmp(pAux->DNI,dni)==0) {
        u=1;
        break;
      }
      else{
        temp=pAux;
        pAux=pAux->sig;
      }
    }
    if (u==1){
      if (pAux==pac)
      {
         // found patient is first on the list
         // update head of list
         pac=pAux->sig;
      }
      else
      {
         // found patient is not the first on the list
         // update link in previous element
         temp->sig=pAux->sig;
      }
      free(pAux);
    }
    else{
      printf("Unknown patient\n");
    }
  }
  return pac;
}

【讨论】:

  • 这解决了问题,我错误地使用了num,所以使用if (pAux==pac) 来检查列表中的第一个元素更符合逻辑。谢谢!
【解决方案2】:

在您的代码中,您没有正确处理删除列表中间或最后一个元素的情况。试试这样的方法,使用 prec 元素来告诉您是否要删除第一个元素 (prec=NULL) 或不删除 (prec!=NULL)。

PPACIENT prec = NULL, pAux;
pAux = pac;
if (pac==NULL) {
    printf("No patients yet\n");
}
else {
    get_string("DNI",9,9,dni);
    while (pAux!=NULL) {
        if (strcmp(pAux->DNI, dni)==0) {
            if (prec==NULL) {// deleting first node
                pac = pAux->sig;
                pAux->sig = NULL;
                free(pAux);
                return pac;
            }
            else if (pAux->next==NULL) { // deleting last node
                prec->sig = NULL;
                pAux->sig = NULL;
                free(pAux);
                return pac;
            }
            else {  // deleting a middle node
                prec->sig = pAux->sig;
                pAux->sig = NULL;
                free(pAux);
                return pac;
            }
        }
        pAux = pAux->sig;
    }
}
printf("Unknown patient\n");
return pac;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-14
    • 2019-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    相关资源
    最近更新 更多