2016-10-24 19 views
2

リンクリストのノードを削除する際に問題があります。これは私のコードです(ただし、addElementの機能は問題ありません)。リストトラフ入力のノードを初期化し、右側のノードを高い値で削除して修正したリストを印刷し、最後にリストを削除する関数を呼び出します。 問題は、特定の入力でプログラムが正しく動作しないことです。 たとえば1,2,3,4,3を入力した場合、出力は1と3(2番目の3つ)ですが、出力は1になります。リンクリストからノードを正しく削除できない

何が問題になりますか?それを理解しているようには見えない。

編集1:以下が含まれます。 編集2:あなたのコードは動作しませんなぜ

#include <iostream> 
#include <stdlib.h> 
#include <stdio.h> 

struct digits { 
    int value; 
    digits *next 
}; 

int main() { 

    int a, b, c; 

    digits *head = NULL, *tale = NULL, *current; 
    cout << "How many digits you want in the linked list?" << endl; 
    cin >> a; 

    for (int i = 0; i < a; i++) { 
    cin >> b; 
    current = new digits; 
    current->value = b; 
    current->next = NULL; 
    if (head == NULL) 
     head = tale = current; 
    else { 
     tale->next = current; 
     tale = current; 
    } 
    if (!cin.good()) { 
     cin.clear(); 
     cin.ignore(256, '\n'); 
     cout << "Input can be int value! You can still input " << (a - i) - 1 
      << " digits." << endl; 
     continue; 
    } 
    } 

    cout << "Want to add element? Press J if so, otherwise any other key" << endl; 
    cin >> add; 
    if (add == 'J') { 
    cin >> c; 
    addElement(&head, c); 
    } 

    removeElement(head); 

    for (current = head; current != NULL; current = current->next) 
    cout << current->value << endl; 
    current = head; 

    while (current != NULL) { 
    head = head->next; 
    delete current; 
    current = head; 
    } 
} 

// function which removes elements which have greater value on right side 
void removeElement(struct digits *head) { 

    struct digits *current = head; 
    struct digits *max = head; 
    struct digits *temp; 

    while (current != NULL && current->next != NULL) { 
    if (current->next->value > max->value) { 
     temp = current->next; 
     current->next = temp->next; 
     free(temp); 
    } else { 
     current = current->next; 
     max = current; 
    } 
    } 
} 
void addElement(struct digits **head, int a) { 

struct digits *newelem = (struct digits*) malloc(sizeof (struct digits)); 
newelem->value = a; 
newelem->next = NULL; 
struct digits *temp = *head; 
if (*head == NULL) { 
    *head = newelem; 
} else { 
    while (temp->next != NULL) 
     temp = temp->next; 
    temp->next = newelem; 
} 
} 
+1

空きと新しく混在させないでください - 削除は新しい – UKMonkey

+0

に一致する呼び出しですこれはすべてが含まれていません。また、フォーマッタを使用してください。あなたが本当に '}}'を書くか、 'struct main'の宣言の後に' int main() 'を置くと、あなたのコードの構造を推論するのは難しくなります。 – Zeta

+0

@RawN一方で、C++は 'std'の上で学ぶべきです。一方、C++開発者は特定の(あまりにも高い)レベルを過ぎても、 'std'が何をしているのか理解し、同様のことを行うことができます(あまり最適化されていません)。 – Angew

答えて

2

:この反復的なアプローチを試してみてくださいあなたが最後に始まり、頭に向かって働くことができれば簡単です。

あなたは、単一リンクリストと直接これを行うことはできませんが、再帰を使用することができます。

最初にリストが空でない場合は、残りのリストを削除します。
次に、右側のノードが大きいかどうかを確認し、存在する場合は削除します。
これで完了です。

void scrub(digits* link) 
{ 
    if (link != nullptr) 
    { 
     scrub(link->next); 
     if (link->next != nullptr && link->next->value > link->value) 
     { 
      digits* scrap = link->next; 
      link->next = link->next->next; 
      delete scrap; 
     } 
    } 
} 
+0

かなりコンセプトコードを試しましたが、エラーが出ます。main.cpp:64:20:error: 'nullptr'がこのスコープ内で宣言されていませんでした。 – screw4445

+0

二重コメントを残して申し訳ありません。これを入力しようとしましたg ++ -std = C++ 0x * .cpp -oは私の.cppファイルのdirでcmdを出力しますが、動作しませんでした。 – screw4445

+0

nullまたはNULLを試してください。 3つのうちのどれでも動作しなければならない。 ;) –

1

はaddElement機能を含ま:

は、このコードをよく見ている:

while (current != NULL && current->next != NULL) { 
    if (current->next->value > max->value) { 
     temp = current->next; 
     current->next = temp->next; 
     free(temp); 
    } 

あなたはcurrentを変更したがされていませんmax。あなたのコードにmaxのvarを持つことはまったく関係がないようです。

実際にはcurrent->next != NULLが失敗したとしてcurrent値は、1で固定されたまま全体maxれ、最終的にwhileループ終了currentが最後のノードである(値= 3)と比較して常に、コードのelse一部に入ることはありません最後のノードのために。したがって、最後のノードを取り除くことができません。その結果、あなたが得る:

1(最初のノード)と3(最後のノード)


ソリューション:これは多くを取得

Node *last, *lastTail = NULL; 
current = *head; 
int last_val = INT_MAX; 
while (current != NULL) { 
    if(current->value > last_val) { 
     last = current; 
     last_val = current->value; 
     current = current->next; 
     if(lastTail) { 
      lastTail->next = current; 
     } 
     else { 
      *head = current; 
      lastTail = current; 
     } 
     delete last; 
    } 
    else{ 
     lastTail = current; 
     last_val = current->value; 
     current = current->next; 
    } 
} 
+0

あなたの答えをありがとう。私はあなたの提案を試みましたが、入力が1のときは1を出力します。2 3 4 3 – screw4445

+1

完全リストを1回トラバースし、削除するリストにノードをマークしてから2回目のトラバースで削除。 –

+1

追加したもう1つのアプローチがあります。間違いなく動作するはずです。 lastTailノード(削除されていないノード)とpreviousNodeValueの値を記録します。この方法では、リストを2回トラバースする必要はありません。 –

関連する問題