2017-02-02 7 views
-1

Я не могу понять, где проблема,C - удалить элемент из отдельного списка

И почему функция del не работает должным образом?

#include<stdio.h> 
#include<malloc.h> 

typedef struct list List; 

struct list 
{ 
    int data; 
    List* next; 
}; 

void prl(List* head); 
void ins(List** head, int value); 
void del(List** head, int value); 

int main() 
{ 
    List* head = NULL; 

    ins(&head, 10); 
    ins(&head, 50); 
    ins(&head, 20); 
    ins(&head, 150); 
    ins(&head, 120); 

    del(&head, 150); 

    prl(head); 

    //freeing dynamically allocated memory for each nodes 

    while(head!=NULL) 
    { 
     List* t = head; 
     head = head->next; 
     free(t); 
    } 

    return 0; 
} 

void prl(List* head) 
{ 
    if(head == NULL) 
     printf("List is empty\n"); 
    else 
    { 
     while(head != NULL) 
     { 
      printf("%d ", head->data); 
      head = head->next; 
     } 
    } 
} 

void ins(List** head, int value) 
{ 
    List* node = malloc(sizeof *node); 

    node->data = value; 
    node->next = NULL; 

    node->next =*head; 
    *head = node; 

} 


void del(List** head, int value) 
{ 
    List* p,*q; 
    p=q=*head; 

    if((*head)->data == value) 
    { 
     *head = (*head)->next; 
     free(p); 
     return; 
    } 
    else 
    { 
     while(p->next != NULL) 
     { 
      if(p->data == value) 
      { 
       q->next = p->next; 
       free(p); 
      } 
      else 
      { 
       q = p; 
       p = p->next; 
      } 
     } // while loop ends 

    } // outer else ends 

} // del function ends 

После запуска этого вывода является пустым, и я думаю, что что-то (логически) является неправильным внутри дель функции внешнего контура еще, однако первое значение может быть удален с помощью этой функции.

+2

Вы пробовали использовать свой код через отладчик? –

+2

Если вы еще не использовали отладчик, теперь самое подходящее время. С помощью отладчика вы можете перешагнуть код по строкам, контролируя переменные и их значения. Разумеется, вы также можете входить в функции, как их называют. Когда у вас возникают подобные проблемы, сначала попробуйте использовать отладчик, чтобы попытаться выяснить проблему. –

+0

Почему ваша функция 'del' удаляет только одну копию значения, если она встречается во главе списка? Но если это не происходит во главе списка, оно выполняет итерацию всего списка и пытается удалить все копии значения? – Kaz

ответ

1

Я думаю, что вы не добавили оператор возврата здесь:

if(p->data == value) 
    { 
     q->next = p->next; 
     free(p); 
     return; 
    } 
+1

Это зависит от того, хочет ли он удалить только первое появление целевого значения или все из них. –

+0

@JohnBollinger да, вы правы, это исправление для удаления первого появления целевого значения. –

2

Несмотря на мой комментарий, я решил помочь вам.

Давайте посмотрим на эти строки:

while(p->next != NULL) 
{ 
    if(p->data == value) 
    { 
     q->next = p->next; 
     free(p); 
    } 
    else 
    { 
     // Irrelevant... 
    } 
} 

Допустим, что условие внутри цикла, p->data == value, случается так, что происходит потом? Вы делаете q->next на p->next, это, вероятно, хорошо, и затем вы продолжаете цикл, не делая p в любом месте.

Когда цикл продолжается p указывает на данные, которые вы только что назвали free, так что разыменование p, например. p->next в состоянии цикла приведет к не определено поведение.

Решение должно обновить p и q соответствующим образом.

+0

спасибо, что дайте мне легко понять, я думаю, что использование 'return;' statement исправляет мою проблему (для удаления первого появления), не так ли? –

+1

@someuser Если вы хотите удалить только первый согласованный элемент, тогда да, вы должны вернуться (или, по крайней мере, выйти из цикла). –

Смежные вопросы