繁体   English   中英

从链表中删除用户输入的字符串节点

[英]Deleting a user-entered string node from a linked list

我正在编写一个 function,它应该从学生的链接列表中删除用户选择的节点。 该程序将通过 read_line function 获取用户输入的学生姓名、姓氏和 email,然后 1) 定位具有这些元素的节点,2) 绕过该节点,以及 3) 释放该节点占用的 memory。 我的function会删除除头节点以外的任何节点,我无法理解我的逻辑是否有错误。

这是我的 function 代码:

struct student* remove_from_list(struct student *list){
  struct student *p;
  struct student *cur;
  struct student *delete = malloc(sizeof(struct student));

  if(delete == NULL){
    printf("\nMalloc failed. \n");
  }
   if(list==NULL){
      printf("\nRoster empty. Nothing to remove.\n");
      return list;
    }

  printf("Enter the last name of the student to be removed: ");
  read_line(delete->last, NAME_LEN);
  printf("Enter the first name of the student to be removed: ");
  read_line(delete->first, NAME_LEN);
  printf("Enter the email of the student to be removed: ");
  read_line(delete->email, EMAIL_LEN);

//to check if student is in the list
  for(p=list; p!=NULL; p=p->next){
    if(((strcmp(delete->last, p->last))!=0) || (strcmp(delete->first,p->first)!=0)
    || (strcmp(delete->email, p->email)!=0)){
      continue;
    }
    else{
      break;
    }
      printf("\nThis student does not exist.\n");
      return list;
    }
  
    //to remove any element other than first
  for(cur=list; cur->next!= NULL; cur=cur->next){ 
    if(strcmp(cur->next->last, delete->last)==0 && 
    strcmp(cur->next->email,delete->email)==0 && 
    strcmp(cur->next->first, delete->first)==0){
      delete=cur->next;
      cur->next = cur->next->next;
      free(delete);
      printf("\nStudent has been removed from the list.\n");
      return list;
    }
  }

cur=list; //to remove first element 
if(cur->next == NULL){
    cur=cur->next;
    free(delete);
    printf("\nStudent has been removed from the list.\n");
    return list;
  }

}

我的 function 没有删除头节点,我不确定这是一个小修复,还是我的逻辑有根本性的错误。 我已经看到使用 integer 输入执行此操作的示例,但在我的案例中很难实现此操作。 任何帮助或建议表示赞赏。

我不确定这是否是你打算做的,但它在逻辑上看起来是错误的......

  for(p=list; p!=NULL; p=p->next){
    if(((strcmp(delete->last, p->last))!=0) || (strcmp(delete->first,p->first)!=0)
    || (strcmp(delete->email, p->email)!=0)){
      printf("\nThis student does not exist.\n");
      return list;
    }
  }

但是,除非第一个节点是您要删除的节点,否则这不会失败吗? 你开始一个循环,查看第一个节点,如果不匹配,你返回列表?

我认为其目的不是寻找否定,而是遍历节点,如果找到匹配项,则尽早结束循环 - 否则您想到达列表的末尾以检查所有节点。

  for(p=list; p!=NULL; p=p->next){
    if(((strcmp(delete->last, p->last))==0) && (strcmp(delete->first,p->first)==0)
    || (strcmp(delete->email, p->email)==0)){
      printf("\nFound a match.\n");
      // delete this node and end this for loop early, probably better to use a while loop here, while(strcmp()!=0 etc);
    }
  }

编辑 既然您已经使用 for 循环来查找记录,您可能想要进行另一次编辑。 您在第一个 for 循环中找到带有 strcmp(),=0 集合的记录,如果它找到了记录。 跳出循环,此时可以删除找到的记录!

这意味着您不需要再次重复循环来删除记录,并且如果它是列表中的第一条记录或后续记录,您将不会有两个不同的代码块。

  //to check if student is in the list
  for(p=list; p!=NULL; p=p->next){
    if(((strcmp(delete->last, p->last))!=0) || (strcmp(delete->first,p->first)!=0)
    || (strcmp(delete->email, p->email)!=0)){
      continue;
    }
    else {
      // we found a match! Delete it
      delete=p;
      p->next = p->next->next;
      free(delete);
      printf("Student has been removed from the list.\n");
      return list;
    }
    printf("\nThis student does not exist.\n");
    return list;
  }
// should never get here any more
} // end func.

如果你真的想保持你的代码原样,因为它对除第一条记录之外的所有记录都有效,那么你需要删除第一条记录才能工作。 == NULL 的检查看起来不对,因为如果没有其他链接到它,您只删除第一条记录? 我觉得这种逻辑是错误的。

  // if we get here, we can assume that the first element matched,
  // because otherwise we should never have gotten here
  cur=list; //to remove first element 
  if(cur->next != NULL){ // if there is a next element
    // set next to be the first
    cur=cur->next;
  }
  free(delete);
  printf("\nStudent has been removed from the list.\n");
  return list;
  
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM