如何删除列表中的第一项?

时间:2013-12-02 08:33:59

标签: c linked-list

我正在构建一个应该删除链表中项目的函数。我的问题是我可以删除任何元素,但不能删除第一个元素,为什么会这样?

我的目标文件:

typedef struct list {
    char *key;
    char *value;
    struct list *next;
} List;

void db_init(List *list) {
    list = malloc(sizeof(db_sizeOfStruct()));

    list->next = NULL;
    list->key = NULL;
    list->value = NULL;
}

void db_delete(char *key, List *list) {
    List *prev;
    db_init(prev);
    int first = 1;

    while(list != NULL) {
        if(strcmp(key, list->key) == 0) {
            if(first == 1) {
                list = list->next; // This is supposed to delete the first item in the list but it does not work...
            } else {
                prev->next = list->next;
            }
            return;
        } else {
            prev = list;
            list = list->next;
            first = 0;
        }
    }
}

在程序的主文件中:

void delete(List *list) {
    printf("key: ");
    char *key;
    key = malloc(sizeof(key)+1);
    readline(key, 128, stdin);

    if(key != NULL) {
        db_delete(key, list);
    }
}

int main(void) {
    delete(list);
    return 0;
}

3 个答案:

答案 0 :(得分:1)

这里有几个问题

首先,你调用db_init,即使你想删除一个元素也会分配一个元素。

其次,您需要考虑如果第一个元素被删除,您需要返回新的第一个元素的地址,但是使用当前函数,您不需要这样做。

原型应该是这样的

void db_delete(char *key, List **list)

或者可能有点整洁,通过返回第一个元素:

List* db_delete(char *key)

所以函数可能看起来像这样

List* db_delete(const char *key, List *list) 
{
  // normally it is not a good idea to use an argument
  // to a function as a loop variable in a function
  // also check arguments to avoid segfaults and 
  // other headaches
  if ( key != NULL && list != NULL )
  {
    List* cur = list;
    List* prev = NULL;

    for ( ; cur != NULL; cur=cur->next )
    {
      // identify if it is the one to delete
      if ( !strcmp(key, cur->key) ) 
      {
        if ( prev != NULL ) // if not first
        {
          List* tmp = cur;
          prev->next = cur->next;
          free(tmp);
          return list;
        }
        else // if first
        {
          List* tmp = cur;
          List* next = cur->next;
          free( tmp );
          return next; 
        }
      }
    }
    prev = cur;
  }
  return list;
}

另一个提示是使用calloc而不是malloc,然后你就不会 需要初始化下一个,因为它们已经是0。

答案 1 :(得分:0)

这是因为你的删除功能无法与调用者通信,列表现在有了新的第一个元素。

最好的解决方法是让它返回列表的新头:

List * db_delete(List *list, const char *key);

答案 2 :(得分:0)

您必须在主页中更改列表变量。如果将指针传递给指向删除函数的指针,例如“delete(List ** list)”

,则可以实现这一点