2016-10-05 4 views
0

Nicht sicher, warum die Knoten immer noch nicht tief kopieren? Der Kopf und die Größe sind tief und kopieren vollkommen in Ordnung.Singlelink List Copy Constructor

Scheint, dass sowohl NewNode-> Data als auch NewNode-> Next nicht tief kopiert werden. Nicht sicher, ob NewNode immer noch auf That -> Data and That -> Next zeigt.

Muss ich beim Erstellen des Knotens die tatsächlichen Werte übergeben?

Vielen Dank im Voraus für alle Antworten. Sehr geschätzt.

Die Liste übergibt (SLList & das).

Knoten ist die Struktur. Knoten verwendet keinen Schwanz. Nur eine nächste und Größe in meinem Fall.

Node* That = that.Head; 

//If not null then deep copy. 
if (That != nullptr) 
{ 
    Head = that.Head; 
    Size = that.Size; 

    //Interate through the list until the end nullptr 
    while (That != nullptr) 
    { 
     Node* NewNode = new Node; 

     NewNode->Data = That->Data; 
     NewNode->Next = That->Next; 
     That = That->Next; 
    } 
} 

//Set the head to null if list passed in is empty. 
else if (That == nullptr) 
{ 
    Head = nullptr; 
    Size = 0; 
} 
+0

Ist es nicht so, dass der Mauszeiger gelöscht wird, nachdem Sie den NewNode-Zeiger innerhalb Ihrer while-Schleife erstellt haben? – Foitn

+0

Vielleicht möchten Sie meinen korrigierten Code sehen. – v78

+0

jemand wird seriell jede Antwort ablehnen, nur weil sie die Frage nicht mögen? Ich mag auch den Code-Stil nicht, aber das ist kein Grund, die Frage nicht zu beantworten. – CashCow

Antwort

-1

Problem 1:

Head = that.Head; 

Whups! Zwei Listen zeigen auf den gleichen Kopf. Das wird nicht gut enden. In der Tat, es besiegt absolut den Punkt einer tiefen Kopie einer verknüpften Liste.

Lösung:

Tun Sie dies nicht.

Problem 2:

while (That != nullptr) 
{ 
    Node* NewNode = new Node; 

    NewNode->Data = That->Data; 
    NewNode->Next = That->Next; 
    That = That->Next; 
} 

NewNode ist nie irgendwo außerhalb der Schleife gespeichert. Das macht diese Schleife zu einem Speicherleckgenerator, der alle Kopien verliert.

Lösung:

die Knoten anzufertigen, wie Sie derzeit tun, sondern speichern die ersten kopierten Knoten in Head.

Problem 3:

NewNode->Next = That->Next; 

Die Kopie zeigt auf einen Knoten in der Liste kopiert werden.

Lösung:

NewNode->Next zum nächsten Knoten auf der Liste zeigen muss. Leider existiert dieser Knoten noch nicht. Sie müssen also zuerst den neuen Knoten erstellen oder Rekursion verwenden.

+0

Ooo, okay ich sehe was du sagst, der Node * NewNode fällt aus dem Rahmen. Ich muss es entweder im Kopf speichern, damit es nicht aus dem Bereich fällt, nachdem die While-Schleife beendet ist. So verliert der Speicher, sobald der Zeiger verloren ist. –

-1
  1. Sie sollten eine neue Liste und der nächste Zeiger sollte nicht nur die Knoten seine Knoten hingewiesen werden, die ursprünglichen Liste erstellen zu können.
  2. Benennen Sie Ihre Variable nie als Mitglieder Ihrer Strukturen und Klassen. Es schafft Verwirrung.

Unten ist der korrigierte Code.

Node* That = that.Head; 

List new_list; 

//If not null then deep copy. 
if (That != nullptr) 
{ 
    new_list.Head=new Node; 
    new_list.Size = that.Size; 
    Node * head = new_list.Head; 

    //Interate through the list until the end nullptr 
    do{ 

     head->Data = That->Data; 
     That = That->Next; 
     if(That!=nullptr){ 
      auto tmp = new Node; 
      head->Next = tmp; 
      head = tmp; 
     } 
    }while(That!=nullptr); 

//Set the head to null if list passed in is empty. 
else if (That == nullptr) 
{ 
    new_list.Head = nullptr; 
    new_list.Size = 0; 
} 

return new_list; 
+0

Ein paar Dinge, die ich in Ihrer Lösung nicht mag: einen Knoten "Kopf" zu nennen, wenn nicht (zuerst, aber dann wird zum Tail) und macht eine Weile (1), wenn Sie hier eine while mit einer Abbruchbedingung oder gar eine for-Schleife verwenden können. – CashCow

+0

@CashCow Nicht ich habe die Variablen benannt, der Fragesteller hat es getan. – v78

+1

@CashCow, schlagen Sie eine bessere Bedingung vor. Ich wählte diese Methode, ich wollte keinen zusätzlichen Knoten erstellen. – v78

-1

Viel, was ich über den Stil der rohen "neuen" Anrufe in Ihrem Code sagen müsste und später aufräumen muss, ist der offensichtliche Fehler, den ich sehe, dass Sie vergessen, sich an Ihren "NewNode" zu "ketten" ketten stattdessen zu That-> Next, das in der Liste ist, die du kopierst.

Als Liste einzeln verknüpft ist, müssen Sie einen Zeiger auf den aktuellen „Schwanz“ zu halten und dann, wie Sie einen neuen Knoten erstellen, setzen Sie (Stil mit)

Tail->Next = NewNode; 
NewNode->Data = That->Data; 
Tail = NewNode; 

Was Sie sind eigentlich Sie erstellen einen Knoten, in dem Sie die Daten klonen, aber Ihre verknüpfte Liste verwendet nicht Ihre neuen Knoten, sondern verwendet immer noch die alten Knoten.

Da dies C++ ist, wo Sie einen Konstruktor haben, sollte NewNode automatisch mit nullptr als "Next" -Wert erstellen. Wenn wir also nicht weiterschleifen, können wir annehmen, dass das gesetzt ist.

template< typename DataType > 
class SLNode 
{ 
public: 
     DataType Data; 
     SLNode<DataType> * Next; 

     SLNode() : Next(nullptr) 
     { 
     } 

     ~SLNode(); // exercise for you to implement 

     explicit SLNode(const DataType& data) 
      : Data(data), Next(nullptr) 
     { 
     } 
}; 

ich gemacht habe alles öffentlich, aber Sie können die Datenelemente privat machen möchten und die Verwendung Getter und Setter haben:

In Wirklichkeit können wir in den Daten, die wir an den Konstruktor benötigen, also auch passieren .

Wie auch immer, jetzt können Sie die folgenden in der Schleife tun ....

while(That) 
{ 
    Tail->Next = new SLNode<DataType>(That->Data); 
    Tail = Tail->Next; 
    That = That->Next; 
} 

Ihr „Kopf“ in der neuen Liste ist auch falsch, wie das zu einem Knoten aus der alten Liste zeigt wird. wir jetzt noch wissen, wie zu schaffen, dass

Head = new SLNode<DataType>(that->Data); 
Tail = Head; 

Wir brauchen Leiter zu halten sowie Schwanz als Schwanz bewegt, wie wir Rekursion, Leiter in der gleichen bleiben und ist der Leiter unserer Liste.

+0

Ich fange an zu denken, dass jemand diese Frage nicht beantworten möchte. – user4581301

+0

Danke für die Antwort, auf jeden Fall eine gute Lektüre. Tut mir leid, wenn ich wie ein Idiot aussehe. Ziemlich neu in C++ für ein paar Monate in. Ich werde es definitiv morgen anschauen, ich gehe ins Bett, es ist 3:50 Uhr lol. Rep ++. Außerdem mussten wir keine Schwanzvariable zum Labor implementieren. –

+0

Die Schwanzvariable befindet sich nur in der Schleife. Sie brauchen es nicht in der Klasse. Sie müssen den Schwanz der Eingabeliste (die Sie That genannt haben) und auch desjenigen, den Sie schreiben, verfolgen. – CashCow