c链表删除功能

时间:2011-12-14 10:14:54

标签: c linked-list

大家好我必须用C编写一个程序而且我不能创建函数deleteByPrice - 函数删除价格超过我必须在控制台输入的所有结构 这是我的结构

 typedef struct  
    {
       char name[20];
       char id[20];
       float price;
    }Type;

typedef struct Details {
    Type data;
    struct Details *next;
}Node;

这就是我的代码,但不起作用:

Node *deleteByPrice(Node *start) {
    Node *cur =start;
    Node *next=start;
    float price;
    printf("Insert the price here : ");
    scanf("%f",&price);
    while(cur){
      if (price < cur->data.price){
            next=cur->next;
            free(cur);
            cur = next;
            start=cur;
            } 
       else {           
            next = cur->next->next;
            free(cur->next);
            cur->next = next;
            }
       }
   return cur;
 }

3 个答案:

答案 0 :(得分:4)

嗯,while循环中的两个分支都不正确。首先,当价格低于您在控制台上给出的价格时,您应该只使用cur = cur->next跳转到下一个元素;无需乱搞链表中的任何项目。其次,当价格高于你给出的价格并且你必须删除该项目时,删除必须按如下方式进行:

  1. 您必须将上一个项目的next指针链接到当前项目之后的项目(即cur->next。因为您只能移动在您的链接中“转发”,这意味着您必须跟踪上一个项目以及当前项目;使用名为prev的额外指针,该指针从空指针开始并且curcur循环的每次迭代中被设置为while之前设置为prev。一旦有prev->next = cur->next,就可以使用free(cur)从列表中删除要删除的项目。(注意,这不会释放项目。)

  2. 从列表中删除要删除的项目后,可以使用cur安全地将其释放,然后转到列表中的下一项。但是,由于free现在是cur->next之后的无效指针,因此您必须首先在释放cur之前在变量中记录cur,然后设置{ {1}}以此记录值继续遍历列表。

  3. 整个解决方案归结为:

    prev = 0; cur = start;
    while (cur) {
        if (cur->data.price < price) {
            /* keep the item and move to the next one */
            prev = cur;
            cur = cur->next;
        } else {
             /* remember the item after the item being removed */
             next = cur->next;
             /* unlink the item from the list */
             if (prev) {
                 prev->next = next;
             }
             /* free the unlinked item */
             free(cur);
             /* move to the next item */
             cur = next;
             /* note that prev does not have to be modified here */
         }
     }
    

    此外,还有一个问题。如果您碰巧从列表中删除了第一项,这意味着调用deleteByPrice的函数持有以访问列表的第一项的指针不再有效,因此您必须当您删除列表的第一项时,相应地更新start,并且必须在函数末尾返回start,以便调用者知道“新的“名单的负责人是。我故意将这个从上面的代码中删除了 - 如果你理解我的代码,那么这不应该太难添加。

答案 1 :(得分:0)

删除节点时,总是修改start,我认为应该指向列表头(第一个元素)。这似乎不对。

如果您要修改的元素实际上是第一个元素,则只应修改start

此外,当您找到要删除的元素时,您似乎需要跟踪上一个元素,以便更改 next - 指针。

答案 2 :(得分:0)

Node *deleteByPrice(Node *start, float price) {
  Node *cur;
  Node **ptr;

  for (ptr = &start; cur = *ptr; ){
    if (cur->data.price < price){
        ptr = &cur->next;
        continue;
        }
    *ptr = cur->next; 
    free(cur);
   }

   return start;
 }