Een kopieerconstructeur maken voor een gelinkte lijst

Dit is huiswerk

Ik ben bezig met de uitvoering van een gekoppelde lijst klasse voor mijn C++ klasse, en de kopie constructeur is erg verwarrend voor mij.

De gekoppelde lijst bestaat uit structuren genaamd Elems:

struct Elem 
    {
        int pri;
        data info;
        Elem * next;
    };
    Elem * head;

info is een aparte, aangepaste klasse die is opgeslagen in de Elem.

De handtekening voor de kopieerconstructeur is:

linkedList::linkedList( const linkedList &v )

Het probleem dat ik heb, neemt meestal mijn logica in en schrijft het daadwerkelijk als code.

Mijn algemene idee is om:

  1. Set Head to v.head (head = v.head)
  2. Stel de waarden Elem aan v’s (PRI = v.pri, info = v.info, next = v.next)
  3. itereren, herhalende stap 2.

Is dit het algemene idee?

Elke hulp zou geweldig zijn. Onthoud, dit is huiswerk, dus geen directe antwoorden alstublieft!

Bedankt voor uw tijd

================================================ ================================================== ================================================== =================

Bedankt voor uw tijd Iedereen!

Ik denk dat ik het heb ontdekt:

//Copy Constructor
LinkedList::LinkedList( const LinkedList &v )
{
Elem * p1 = 0;//current
Elem * p2 = 0;//next
if( v.head == 0 )
    head = 0;
else
{
    head = new Elem;
    head -> pri = v.head -> pri;
    head -> info = v.head -> info;
    p1 = head;
    p2 = v.head -> next;
}
while( p2 )
{
    p1 -> next = new Elem;
    p1 = p1 -> next;
    p1 -> pri = p2 -> pri;
    p1 -> info = p2 -> info;
    p2 = p2 -> next;
}
p1 -> next = 0;
}

Ik ben er vrij zeker van dat dat werkt. Ik heb wat logische foto’s gemaakt om te helpen, en ik ben geen problemen tegengekomen.


Antwoord 1, autoriteit 100%

Je moet voorzichtig zijn met stap 1 en een deel van stap 2. Stap 1 moet een nieuwe node toewijzen en die gebruiken als de head. In stap 2 is het gedeelte over next = v.next, tenzij het de bedoeling is om een oppervlakkige kopie te maken, onjuist.

Als je een container kopieert, zoals een gekoppelde lijst, wil je waarschijnlijk een diepe kopie, dus er moeten nieuwe knooppunten worden gemaakt en alleen de gegevens worden gekopieerd. De nexten prioraanwijzers in de knooppunten van de nieuwe lijst moeten verwijzen naar nieuwe knooppunten die u specifiekvoor die lijst maakt en niet de knooppunten uit de originele lijst. Deze nieuwe knooppunten zouden kopieën hebben van de corresponderende gegevens uit de originele lijst, zodat de nieuwe lijst kan worden beschouwd als een op-waarde of diepe kopie.

Hier is een foto die de verschillen laat zien tussen oppervlakkig en diep kopiëren:

Merk op hoe in het Deep Copygedeelte van het diagram, geen van de knooppunten naar knooppunten in de oude lijst verwijst. Voor meer informatie over het verschil tussen ondiepe en diepe kopieën, zie het Wikipedia-artikel over kopiëren van objecten.


Antwoord 2, autoriteit 17%

  1. Je moet this->head = v.headniet instellen. Omdat het hoofd gewoon een wijzer is. Wat u moet doen, is een nieuwe kop maken en de waarden afzonderlijk van v.headnaar uw nieuwe kop kopiëren. Anders zou je twee verwijzingen naar hetzelfde hebben.

  2. Je zou dan een tijdelijke Elem-aanwijzer moeten maken die begint met v.headen de lijst doorlopen, waarbij de waarden worden gekopieerd naar de nieuwe Elemverwijst naar de nieuwe kopie.

  3. Zie hierboven.


Antwoord 3, autoriteit 8%

Wat moet uw copy-constructor kopiëren? Het zou primoeten kopiëren – makkelijk. Het zou infomoeten kopiëren – ook gemakkelijk. En als nextniet null is, moet het deze ook kopiëren. Hoe kun je nextkopiëren? Denk recursief: Nou, nextis een Elem *, en Elemheeft een kopie-constructor: gebruik deze gewoon om de Elemen verwijs ernaar.

Je kunt dit ook iteratief oplossen, maar de recursieve oplossing is veel intuïtiever.


Antwoord 4

Dus hier is mijn antwoord (weet niet of dat bij je huiswerk past – instructeurs hebben soms hun eigen ideeën;):

Over het algemeen moet een kopieerconstructor uw object “kopiëren”. D.w.z. stel dat je linkedList l1 hebt en doe een linkedList l2 = l1 (die linkedList::linkedList(l1) aanroept), dan l1 en l2
zijn totaal afzonderlijke objecten in die zin dat wijziging van l1 geen invloed heeft op l2 en vice versa.

Als je alleen aanwijzers toewijst, krijg je geen echte kopie, omdat het verwijderen van referenties en het wijzigen van een van beide van invloed zou zijn op beide objecten.

Je wilt liever een echte diepe kopie maken van elk element in je bronnenlijst (of alleen een kopie op aanvraag doen, als je zin hebt).


Antwoord 5

Je bent de regel vergeten
return;
na

if( v.head == 0 )
    head = 0;

U moet uitkomen, toch?

Other episodes