0

!=私は現在、list と int を引数として取り、int が見つかって削除された場合は true を返し、リストに見つからなかった場合は false を返す次の erase recursive bool 関数に取り組んでいます。動作しているように見えますが、問題は、現在のではなく、リスト内の次の int 番号を削除することです:

 typedef struct E_Type * List;

 struct E_Type
 {
        int data;
        List next = 0;
 };

bool erase(const List & l, int data){
List current = l;   
if (current == 0)
{
   return false;
 }
else if (current->data == data)
{
      List deleteNode = new E_Type;
     deleteNode = current->next;//probably this causes the error, but how can I point it to the current without crashing the program
     current->next = deleteNode->next;
     delete deleteNode;
     return true;
}

else if (current->data != data)
{
      return erase(current->next, data);
}


}
4

7 に答える 7

2

リストには 2 つの基本的なタイプがあります。

  • 単一リンクリスト (各ノードは次のノードを知っている) および
  • 二重リンク リスト (各ノードは、前のノードだけでなく次のノードも認識します)。

あなたの場合のように、単一リンクリストがある場合は、現在のノードが「データ」と等しいかどうかを確認してはなりません。その時点で最後のノードの次のポインターを変更するには遅すぎるためです。したがって、次のように、常に NEXT ポインターが等しいかどうかを確認する必要があります。

bool erase(const List & l, int data)
{
    List current = l;   
    if (current == 0)
        return false;

    // special case: node to be deleted is the first one
    if (current->data == data)
    {
        delete current;
        return true;
    }

    if (current->next && current->next->data == data) // next exists and must be erased
    {
        List deleteNode = current->next;   // Step 1: save ptr to next
        current->next = deleteNode->next;  // Step 2: reassign current->next ptr
        delete deleteNode;                 // Step 3: delete the node
        return true;
    }

    return erase(current->next, data);
}

注:最後の「else if」条件は省略しました。'else' は、前の if に戻りがあったためであり、'if' は、その条件が前の 'if' の否定であったためです。これは、プログラムがここまで来ると、常に保持されます。

よろしく

于 2012-12-06T14:24:52.897 に答える
1

リストがある場合:
A --> B --> C --> D
そして C を削除したい場合:
C を temp 変数に
保存 B->next=C->next を
削除 C
それを変更できるようにするには、B を見つける必要があります。
E_type の新しいインスタンスを作成しないでください。

于 2012-12-06T14:11:09.493 に答える
1

あなたの状態

else if (current->data == data)

値データを持つノードで停止します。次に、コード内のこのノードの後のノードを削除します。

コードの残りの部分を同じに保ちたい場合、その行は次のようになります。

else if ((current->next)->data == data)

最初の要素がリスト内の唯一の要素である場合に備えて、追加のチェックを行います。

より簡単な方法は、現在の要素の前の要素を指すポインターを保持し、そのポインターによって参照されるノードを削除することです。

于 2012-12-06T14:10:46.110 に答える
1

ここにいくつかの指針があります。

反復アプローチ

リストを反復処理する場合、現在の要素へのポインターを維持するだけでは不十分です。現在の要素を削除すると修正が必要になるため、の要素へのポインターも保持する必要があります。previous->next

その上、リストの最初の要素を削除するには、特別な処理が必要になります。

再帰的アプローチ

リストの先頭へのポインターを受け取り、必要な要素を見つけて削除し、リストの新しい先頭へのポインターを返す再帰関数を作成します。これを行うには、次のことが必要です。

  1. 基本ケースを定義して実装します。1 要素リストの処理は自然な候補のように思えます。
  2. 再帰を定義します。リストの先頭が探している要素であるか、そうでないかの 2 つのケースがあります。どちらの場合も何をする必要があるかを把握し、そこから実行してください。
于 2012-12-06T14:04:43.230 に答える
1

検討している唯一のノードは現在のノードであるため、変更するための準備が必要ですl

if (current->data == data)
{
  l = current->next;
  delete current;
  return true;
}
于 2012-12-06T14:08:00.137 に答える
0

リストからノードを削除するときは、前のノードが次のノードを指すようにする必要があります。単独でリンクされたリストがあるため、2 つのオプションがあります。

  1. 関数内の前のノードへのポインターを維持しますerase。目的のノードに遭遇したら、前のノードを現在のノードにリンクしcurrent->next、削除します。リストの最初のノードには特別な処理が必要です。

  2. 目的のノードが見つかったら、 の内容を にコピーしてcurrent->nextからcurrent、 を削除しcurrent->nextます。この方法では、関数に追加のパラメーターは必要ありません。リストの最後のノードには特別な処理が必要です。

于 2012-12-06T13:55:33.703 に答える
0

のエントリのnextポインタを変更する必要があります。したがって、すべてが見つかりますが、current->data ではなく、current->next->data をデータに対してチェックする必要があります。

current がリストの最後のエントリである場合は、必ず NULL ポインタをチェックしてください!

于 2012-12-06T14:08:25.423 に答える