1

ctorc-styleと。のリンクリストがありdtorます。

このifステートメントがtrueをテストしないことを決定したとき、私はあまりにもイライラし、無限ループに陥りました。なぜそれが真にテストされないのか理解できません。

からノード(クラスオブジェクトのアドレス)を削除しようとしていますLinkedList

多分誰かが私を助けることができますか?

Node *Current = first_; // I want this to be my only Node Ptr Varaible Declaration.
if ( NULL == first_ )
std::cout << "Cannot delete from an empty list: \n";


while ( Current != NULL )
{
  if ( first_->data_ == node->data_ ) 
  {
    //check to see if we are deleteing the head.
    first_ = first_->next_;
    --listLen_;
    delete Current;
    std::cout << "Head Deleted!\n";
  }
  if ( Current->data_ == node->data_ ) // FOR SOME REASON this is never true?
  {
    --listLen_;
    node->data_ = NULL;
    Current     = Current->next_;
    node->data_ = Current;
  }
  else  // we must not of found it.  // else should match previous i
  {
    Current->prev_ = Current;// since we are not deleting the first node we are OK here.
    Current        = first_->next_;

    if ( Current->next_ == NULL ) // see if we are at the end of the list.
    {
      first_ = NULL;  
      last_  = Current->prev_;

    }
  }
}
return;
4

7 に答える 7

2

問題が多すぎるので、これは本当に書き直す必要があります...また、STLコンテナを使用しないのはなぜですか?これは宿題の質問だと思います。

無限ループへの答えは、次のノードにインクリメントするelseの場合です。

Current        = first_->next_;

これにより、最初の2つのノードでデータが見つからない場合、永久ループになります...次のテストは常に最初の次のノードに設定され、2つ以上のノードがある場合は現在のノードがNULLに設定されることはありません。リスト内。

于 2009-05-27T18:22:05.973 に答える
1

あなたが何を達成しようとしているのか完全にはわかりませんが、あなたがそれを間違っていると確信しています。node-> data_に一致する二重リンクリストから要素を削除しようとしているだけの場合は、次のように簡単です。

Node *Current = first_;

while (Current != NULL)
{
  if (Current->data_ == node->_data)
  {
    //If Current isn't the head of the list, set prev to next
    if (Current != first_)
      Current->prev_->next_ = Current->next_
    else
    {
      first_ = Current->next_;
      if (first_ != NULL)
        first_->prev_ = NULL;
    }

    //If Current isn't the tail of the list, set next to prev
    if (Current->next_ != NULL)
      Current->next_->prev_ = Current->prev_
    else if (Current->prev_ != NULL)
      Current->prev_->next_ = NULL;


    delete Current;
    Current = NULL;
  }
  else
  {
    Current = Current->next_;
  }
}
return;
于 2009-05-27T18:23:23.977 に答える
0

ここでは実際の質問に対する答えではなく、提案です。

リンクリストを繰り返し処理して、リスト内のエントリを削除することは決してありません。各エントリには有効な次と前のポインタが必要です。リストからエントリを削除する場合は、前のレコードが次のレコードを指すようにし、その逆を行ってリストから自分自身を削除します。空のリストには、相互にポイントするだけのヘッドレコードとテールレコードが必要であり、その間にすべての有効なエントリが挿入されます。

于 2009-05-27T19:56:19.590 に答える
0

nodeどこから来たのか、どのように定義されているのかは示していませんdata_が、ポインタタイプの場合は、アドレスではなく内容を比較する必要があります。

data_それが何かへのポインタであり、それが指すものがoperator==定義されているか、組み込み型であり、探している値を持っていると仮定すると、代わりにこれを行うことができます。

if ( *Current->data_ == *node->data_ )
于 2009-05-27T18:16:01.947 に答える
0

iffirst_->data_ == node->data_がtrueと評価されると、2番目のifステートメントは常にtrueと評価され、2番目のif条件は常にfalseと評価されますCurrent->data_ == node->data_ 。これは、最初の反復で、更新せずfirst_ == Currentに削除するためです。Current

リンクリストからノードを削除するには、あまりにも多くの作業を行っているようです。

于 2009-05-27T18:23:11.683 に答える
0

ループを小さくして、何が悪かったのかを簡単に把握できるようにします。データ比較が理にかなっていると仮定して、これを次のように見てください。

curr = first_;
while( curr && (curr->data_ != node->data_) ) { 
  curr = curr->next_; 
}
if (!curr) return   // didnt find it, nothing to remove
if ( curr == first_ )   
  first_ = curr->next_  
else            
  curr->prev_->next_ = curr->next_
curr->next_->prev_ = curr->prev_ // always fix next's prev
delete curr
于 2009-05-28T17:29:04.337 に答える
0

渡された値を持つノードを削除します。

void deleteBegin()
{
 Node* temp =Head;
 if(temp==NULL)
     return;
 Head=Head->next;
 free(temp);
}
void deleteMiddle(int _data)
{
 Node* curr = Head;
 Node* prev = Head;

if(curr==NULL)
    return;

if(curr->next==NULL)
  {
    deleteBegin();
    return;
 }

 while(curr->next!=NULL && curr->data!=_data)
 {
    prev=curr;
    curr=curr->next;
 }

 if(curr->data == _data)
 {
     if(prev==curr)
     {
        deleteBegin();
        return;
      }
    prev->next = curr->next;
    free(curr);
 }  
 else
 {
    cout<<"Element Not Found\n";
    return;
 }

}
于 2017-04-26T14:09:23.833 に答える