2017-02-02 8 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'関数は、リストの先頭にある値のコピーを1つだけ削除するのはなぜですか?しかし、それがリストの先頭に現れなければ、リスト全体を反復し、その値のすべてのコピーを削除しようとしますか? – Kaz

答えて

1

私はあなたがここにreturn文を追加していないと思う:

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->nextp->nextを指すようにすると、それはおそらく問題ありません。pを他の場所に指定しなくてもループを続けることができます。

pは、freeと呼ばれているデータを指しているので、参照番号pなどを参照してください。ループ状態のp->nextは、の未定義の動作になります。

解決策はpqを適切に更新することです。

+0

私は簡単に理解できるように感謝します、私は 'return;'ステートメントが私の問題を修正していると思います(最初のオカレンスの削除のためです)? –

+1

@someuser最初に一致する要素だけを削除したい場合は、yesを返します(または少なくともループを終了する必要があります)。 –

関連する問題