0

二重リンクリストの最後に値を挿入しようとしています。先頭または最初のノードに値を挿入できますが、2番目の値が挿入されません。

ここでの問題は、2番目の値を入力しているときです

class d_list
{
private:

    struct node
    {
        double data;
        node *next;
        node *previous;
    };

    node *first;
    node *last ;
public:
    d_list(void)
    {
        first = nullptr;
        last = nullptr;
    };
    void append(double);

};

void d_list::append(double num)
{
    node *ptr;
    node *toinsert;
    if(!first)
    {
        first = new node;
        first->previous= nullptr;
        first->data = num;
        last= new node;
        first->next= last->previous;
        last->previous = first->next;
        last->next= nullptr;

    }
    else
    {
        if(last->next == nullptr)
        {
            ptr = new node;
            ptr->next =last->previous;
            ptr->data=num;
            last->previous = ptr->next  ;
        }


        last->next= nullptr;
    }

}


int _tmain(int argc, _TCHAR* argv[])
{
    d_list aa;
    cout<<"going to append first"<<endl;
    aa.append(44);
    cout<<"going to append second"<<endl;
    aa.append(50.5);

    return 0;
}
4

5 に答える 5

3

コードにいくつかの問題があります。

  • nodeのメンバーと前のメンバーはどこでも初期化されることはなく、その結果、使用時に未定義になります。にコンストラクターを追加するか、node割り当て後にコンストラクターが初期化されるようにします。
  • 空のリストへのノードの追加は正しくありません。first->nextは未定義のままですが、なぜ最初と最後の2つのノードを作成するのですか?1つの要素を持つリストでは、次にfirst == last。最初/最後の次/前の設定も意味がありません。
  • 整形式の二重リンクリストlast->nextでは、そうであるように、常にnullである必要がありますfirst->previous
  • 空でないリストへのノードの追加も正しくありません。
  • 例では示していませんが、最終的には、デストラクタと、コピー演算子およびコピーコンストラクタ(3つのルール)が必要になります。現時点ではメモリリークが発生しており、ノードを削除しようとすると、ダブルフリーでクラッシュする可能性があります。

二重リンクリストの背後にある概念を正しく理解できるように、コードから少し離れることをお勧めします。次/前の矢印を使用して紙にリストを描き、空の/空でないリストにノードを追加するときにそれらを変更する必要がある方法と、ノードを削除して移動する方法を確認します。next / prevをどのように設定するかを理解したら、それをコードに変換するのは比較的簡単です。

コメントに答えるために編集:新しいノードを追加するには、技術的にどこにでも追加できますが、通常は最後に追加されます(少なくとも私が見たものから)。空のリストと空でないリストに新しいノードを追加するための完全で正しいコードについては、他の回答を参照してください。

于 2012-02-26T14:49:27.887 に答える
2
...
if(last->next == nullptr)
{
  ptr = new node;
  ptr->next =last->previous; // <- is not correct
  ptr->data=num;
  last->previous = ptr->next  ; // <- does not do anything useful
  ...

新しいノードをリストに追加しません。

...
if(!last->next)
{
  ptr = new node;
  ptr->previous=last->previous;
  ptr->next =last;
  ptr->data=num;
  last->previous = ptr  ;
  ...

より良いはずです。ちなみに、デストラクタで割り当てられたメモリを削除してください!

于 2012-02-26T14:44:52.727 に答える
2

私はあなたの二重リンクリストを次のコードで書きます:

    #include <iostream>
    using namespace std;
    class d_list
    {
    private:

        struct node
        {
            double data;
            node *next;
            node *previous;
        };

        node *first;
        // node *last ; no need for bidirectional list
    public:
        d_list(void)
        {
            first = nullptr;
            //last = nullptr;
        };
        void append(double);

    };

    void d_list::append(double num)
    {
        node *ptr = new node;
        ptr->data = num;
        node *toinsert;
        if(!first)
        {
            first = ptr;
            first->previous=first->next=first;
        }
        else
        {
            if(first->next == first)
            {
                ptr->next = ptr->previous = first;
                first->next = first->previous = ptr;
            }
            else{
                node *last = first->previous;
                ptr->next = first;
                ptr->previous = last;
                last->next = ptr;
                first->previous = ptr;
            }
        }
    }


    int _tmain(int argc, _TCHAR* argv[])
    {
        d_list aa;
        cout<<"going to append first"<<endl;
        aa.append(44);
        cout<<"going to append second"<<endl;
        aa.append(50.5);

        return 0;
    }
于 2012-02-26T14:45:59.570 に答える
1

なぜ宣言を挿入したのnode *ptr;です node *toinsert;か、それを使用しないのですか?また、最後に1つのノードを挿入する場合は、新しい要素を1つだけ作成する必要があることも明らかです(最初がnullの場合はnewを2回呼び出します)。

于 2012-02-26T14:47:27.153 に答える
1

このコードを試してください...

class d_list 
{


private:
      struct node
      {
         double data;
         node *next;
         node *previous;
     };
      node *first;
     node *last ;

 public:
     d_list(void)
     {
         first = nullptr;
         last = nullptr;
     };

     void append(double);
  }; 

 void d_list::append(double num)
 {
     node *ptr;
     node *toinsert;
     if(!first)
     {
         first = last = new node;
         first->previous= nullptr;
         first->next = nullptr;
         first->data = num;
     }
     else
     {
             ptr = new node;
             ptr->next =last->previous;
             ptr->data=num;
             last->previous = ptr->next  ;
     }
  }


 int _tmain(int argc, _TCHAR* argv[])
 {
     d_list aa;
     cout<<"going to append first"<<endl;
     aa.append(44);
     cout<<"going to append second"<<endl;
     aa.append(50.5);
      return 0;
 } 
于 2012-03-07T11:12:56.513 に答える