【问题标题】:Removing an element from a doubly linked list从双向链表中删除元素
【发布时间】:2013-08-29 09:20:06
【问题描述】:

我的代码适用于链表开头的元素,但不适用于中间或末尾的元素。感谢您的帮助!

void remove(){
    if (!head)
        printf("\nNo nodes to delete. List is empty.");
    else{
        int n;
        struct node* help = head;
        printf("Enter an element to delete: ");
        scanf("%d", &n);
        if(head->data == n){
            help-> next->prev = 0;
            head = help -> next;
        } else{
            while(help -> next){
                if(help -> data == n){
                    help -> next -> prev = help -> prev;
                    help -> prev -> next = help -> next;
                }
                else help = help -> next;
            }
        }
    }   
}

【问题讨论】:

  • 为什么不把n作为remove()的参数?
  • @meaning-matters 为什么人们总是挑代码而不是回答提出的问题?您的问题与所提出的问题无关,并且发布的代码很可能会被简化以发布到 SO - 而不是提问者为实际项目实际编写的方式。
  • @shail 为我们提供有关它如何失败的具体示例会很有帮助,因为您的代码有很多问题,而且如果不为您重写代码就很难将它们全部指出(这不应该是在SO上完成)
  • @xaxxon 总的来说,我的程序是用于在排序的双向链表中插入和删除节点。插入工作并从链表中删除第一个节点工作正常,除了删除最后一个节点。此外,删除中间和末尾的节点不起作用。如果我尝试删除最后一个节点,我会被引导回 main();如果我尝试删除中间的节点,程序会崩溃:|

标签: c pointers logic structure doubly-linked-list


【解决方案1】:

首先,使用 NULL 而不是 0 来表示 NULL。在 C 中,你需要。在 C++ 中它是可选的,但您标记了问题 C。

help-> next->prev = 0;

你永远不会检查是否有第二个元素。如果列表只有一个元素,则会失败 - 因此它甚至并不总是适用于第一个元素。

        while(help -> next){
            if(help -> data == n){

这将阻止您删除最后一个元素,因为一旦您到达(但在处理之前)最后一个元素,您就会停止查看列表。但即使你没有,下一行:

                help -> next -> prev = help -> prev;
                help -> prev -> next = help -> next;

如果它是最后一个,会导致你崩溃,因为它没有检查后面是否有另一个元素。

此外,箭头-> 前后的空格也很少见。我建议不要再这样做了。

【讨论】:

  • 感谢您指出这些问题。我会尝试纠正我的代码。
  • 我是否应该添加一个 if 条件(仅在 next 不为 null 时才执行)来执行 help->next->prev = NULL;?另外,我应该将我的 while 条件更改为 while(help) 吗?我不知道如何更改 while 循环中的代码。
  • @Shail 是的。会有很多条件
【解决方案2】:
struct node *head, *tail; //global head & tail

int delete_item() {
    int del_data = 0;
    struct node *item = head, *tmp;
    scanf("%d", &del_data);
    while(item){
        if(item->data == del_data){
            tmp = item;
            if(item->next){
                //it's not tail
                item->next->prev = item->prev;
            } 
            else {
                //it's tail
                tail = item->prev;
                if(tail)
                    tail->next = NULL;
            }
            if(item->prev){
                //it's not head
                item->prev->next = item->next;
            }
            else {
                //it's head
                head = item->next;
                if(head)
                    head->prev = NULL;
            }
            //free memory
            free(tmp);
        }
        //move forward
        item = item->next;
    }
return 0;
}

【讨论】:

  • 如果他会尝试理解这段代码,那么一切都会好起来的。不要那么刻薄。
【解决方案3】:

我不小心处理了这个问题,直到我找到了删除节点的方法 在给定的位置:

void delete (int n) {
  struct node *temp = head;
  if (n == 1) {
    head = temp->next;
    (temp->next)->prev = head;
    free(temp);
    return;
  }
  for (int i = 0; i < n - 1; i++) {
    temp = temp->next;
  }
  if (temp->next != NULL) {
    (temp->next)->prev = temp->prev;
    (temp->prev)->next = temp->next;
  } else {
    (temp->prev)->next = NULL;
  }
  free(temp);
}

【讨论】:

    猜你喜欢
    • 2014-03-04
    • 1970-01-01
    • 2021-11-22
    • 2018-09-16
    • 1970-01-01
    • 1970-01-01
    • 2020-10-29
    • 2011-08-18
    相关资源
    最近更新 更多