c-如何删除我列表中的第一项



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

我的目标文件:

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

这里有几个问题

首先,调用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,然后就不用了需要初始化next、prev,因为它们将已经是0。

这是因为删除函数无法与调用方通信,所以列表现在有了一个新的第一个元素。

最好的解决方案是让它返回列表的新标题:

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

您必须更改main中的列表Variable。如果您将一个指针传递给一个指向删除函数(如"delete(List**List)"

)的指针,就可以实现这一点

相关内容

  • 没有找到相关文章

最新更新