从双向链表中删除元素

时间:2013-08-29 09:20:06

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

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

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

3 个答案:

答案 0 :(得分: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;
如果它是最后一个,

将导致你崩溃,因为它没有检查之后是否有另一个元素。

此外,箭头->之前和之后的空格非常罕见。我建议不再这样做了。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

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