2017-08-20 9 views
0

私はデータ構造を練習しており、単リンクのリストを作成し、リストに追加してリストを削除するコードを実装しました。私は本当に私の削除リスト機能が実際に何をすべきかをしているかどうかを知りたいと思う。私はそれがクラッシュする削除の後にリストを印刷しようとすると、それはだと思う。それで、自分のリストを削除していることを保証するためのアドバイスや、自分のコードを改善するためのアドバイスがあります。動的にメモリを割り当てることになると、私はまだまだ新人です。単独リンクされたリストのリストを削除する

typedef struct node { 
    int data; 
    node* next; 
}* nodePtr; 

nodePtr addToList(nodePtr head, int data) { 
    nodePtr newItem = new node; //create a new item 

    newItem->data = data; //assign the data to the new item 
    newItem->next = head; //point to head 

    return newItem; //return the new head 
} 

void deleteList(nodePtr head) { 
    if (head == nullptr) { 
     return; 
    } 
    else { 
     deleteList(head->next); 
     delete head; 
     head = nullptr; 
    } 
} 

void Print(nodePtr n) { 
    while (n != nullptr) { 
     cout << n->data << " "; 
     n = n->next; 
    } 
} 

int main() { 
    nodePtr head = new node; 
    nodePtr second = new node; 
    nodePtr third = new node; 

    head->data = 1; 
    head->next = second; 

    second->data = 2; 
    second->next = third; 

    third->data = 3; 
    third->next = nullptr; 

    Print(head); 
    cout << endl; 

    head = addToList(head, 0); 

    Print(head); 
    cout << endl; 

    deleteList(head); 

    return 0; 
} 
+0

問題を見つけて修正するために、デバッガを使用してコードを1行ずつ進めることをお勧めします。 – user0042

+0

あなたのaddToListは、それがするべきことをしていません。 addToList関数を呼び出さずにdeleteを呼び出してそこから修正してみてください。あなたのメインでは、リストを手動で作成するのではなく、addToListを使用していません。 –

+0

あなたが割り当てたものを正しく整理しているかどうかを判断するには、valgrindのようなツールを試すことができます。 – aschepler

答えて

2

お電話:

deleteList(head); 

headは、その文の後NULLに等しくなりません。

deleteList(head); 
head = NULL; 

か::私たちはdeleteListのために参照パラメータを使用し

void deleteList(nodePtr & head) { 
    if (head == nullptr) { 
     return; 
    } 
    else { 
     deleteList(head->next); 
     delete head; 
     head = nullptr; 
    } 
} 

ノート代わりに、あなたのような何かをする必要があります。

1

あなたの機能は、ビルの答えに指摘されている小さな注意の他に、ほとんど正しいです。

リストを削除するために本当に再帰が必要ないことを指摘したかっただけです。ここに別の方法があります。

while(head != nullptr) { 
    node *deleteMe = head; 
    head = head->next; 
    delete deleteMe; 
} 
1

私はコードをクリーンアップするために、このようなものを追加します。

nodePtr create_node(int n) { 
    nodePtr p = new node; 
    assert (p != NULL); 
    p -> data = n; 
    p -> next = NULL; 
} 

、あなたのようなループを使用して、テストのためのあなたの主な機能をクリーンアップすることができ、この方法:

for (int i = 0; i < 10; ++i) { 
    nodePtr p = create_node(i); 
    head = addToList(head, p); 
} 

そして、参照によって頭のポインタを渡すので、次のようなものになります:

nodePtr addToList(nodePtr&head, nodePtr newItem) { 
    newItem->next = head; //point to head 
    head = newItem; 
} 

これらはほとんどスタイルの変更だけですが、メイン関数でノードを個別に作成するのではなく、プログラムをテストするのが簡単になり、コードが少しきれいに見えます。あなたが行うことができるもう1つのことは、このリストを反復的に最初に削除しようとすることです。再帰的な削除がより理にかなっていると実装した後です。実際にそれをデバッグし、あなたが正しく最善の方法を、メモリの割り当てを解除しているかどうかを確認するには

は、デバッガを使用することで、あなたは(アサートに追加することもできます)null値を検証するために、それは、コマンドラインのgdbのようなものを(チェックアウトする価値があります): https://www.cs.cmu.edu/~gilpin/tutorial/。このチュートリアルは実際にリンクされたリストのメモリ割り当てをデバッグするのに役立ちますので参考にしてください。

関連する問題