Kopie einer Liste!
-
Versteh ich das richtig das ich eine Kopie einer Liste nur richtig erstellen kann wenn man jedes Element was in der Liste enthalten ist in der neuen Liste Speichert?
Wenn man nämlcih direkt die beiden Listen = setzt und dann in der kopierten Liste etwas löscht es auch gleichzeitig in der neuen Liste entfernt wurde!!
Oder gibt es noch einen anderen weg??
-
Hi,
du siehst das richtig. I.A. musst du jedes Element kopieren und in
der neuen Liste anordnen.I.A. schreibt man sich dafür eine Funktion, die direkt auf der
Struktur arbeitet und nicht vorhandene Funktionen wie insert() oder so
verwendet.Gruß mcr
-
Wieso insert() nicht nutzen, wenn man die Funktionen doch hat???
-
Kommt drauf an, wie die Funktion implementiert ist.
Z.B. Wenn du eine einfach verkettete Liste hast und insert() das
neue Element immer an das Ende der Liste anhängt, dann muss bei
jedem insert() die gesamte Liste durchlaufen werden.Beim Kopieren kannst du dir, den Pointer aufs letzte Element merken
und dadurch geht es schneller.Oder wenn die insert()-Funktion das Element am Anfang der Liste
einfügt, ist die Reihenfolge umgekehrt, was auch nicht im Sinne einer
Kopierfunktion ist. Um das zu umgehen, müsste man die Elemente
in umgekehrter Reihenfolge einfügen, was bei einer einfach-verketteten
Liste auch nicht schnell geht.Wenn du in deiner Liste stets einen Pointer aufs erste und aufs letzte
Element hast, dann kann man die insert()-Funktion effizient programmieren.
Aber das bedeutet auch, dass du ein wenig mehr Speicher spendieren mußt.Ich würde daher die insert()-Funktion vermeiden und direkt die Liste
erzeugen.Gruß mcr
-
Thes-One schrieb:
Wenn man nämlcih direkt die beiden Listen = setzt und dann in der kopierten Liste etwas löscht es auch gleichzeitig in der neuen Liste entfernt wurde!!
kommt auf den Aufbau der Liste an. Wenn du Listen mit Zeigern erstellt hast, dann musst du bei der Kopie für jedes Element neuen Speicher allozieren und das Element kopieren. Wenn du mit mit = eine Kopie erstellst, dann wird nur bitweise kopiert, d.h. die Zeiger der Kopie zeigen auf die originalen Elemente und wenn diese freigegeben/verändert werden, sind die Elemente der Kopie ebenso freigegeben/verändert. Dir sollte klar sein, dass eine Kopie eines Zeiger (zeiger2 = zeiger1; ) keinen neuen Speicher reserviert oder so.
@mcr: was meinst du mit deinem zweiten Absatz? Ich kann nicht verstehen, was du da meinst.
// edit: @mcr: hab zu lange für meine Antowrt gebraucht
eine insert() Funktion durchläuft nicht immer die gesammte Liste: Wenn der Kopf der Liste einen Zeiger auf das letzte Element hat, kann man in O(1) Elemente ans Ende der Liste einfügen.
-
Es gibt zwei trivale Möglichkeiten insert() für einfach verkettete
Listen zu implementieren.1. insert() fügt das neue Element ans Ende der Liste an.
Wenn du diesen Pointer nicht hast, musst du durch die gesamte Liste laufen.2. insert() fügt das neue Element an den Anfang der Liste an.
Dann ist die Reihenfolge der kopierten Liste umgekehrt zur original Liste,
was auch i.d.R. nicht gewünscht ist.
Eine Lösung dafür: Die Elemente werden in umgekehrter Reihenfolge eingefügt.
Aber i.d.R. hat man dann auch nicht den Pointer aufs letzte Element
einer einfach verketteten Liste, also muss man jedes mal wieder durch die
Liste durch.Daher ist das folgende *Pseudocode* einfacher:
liste copy_list (liste orig) { liste neu = NULL, tmp = NULL; while (!orig) { liste el = malloc(sizeof(*el)); kopiere die Eintraege des Elements orig (*el = *orig) next-Pointer von el initialisieren (mit NULL z.B.) if (!tmp) { neu = el; tmp = neu; } else { tmp->next = el; tmp = el; } orig = orig->next; } return neu; }
Dies sollte im groben funktionieren.
Gruß mcr
//edit: diesmal war ich auch zu langsam: Wenn man ein Listen-Kopf hat, stimmt
das. Aber wenn du eine Liste ohne explizites Kopf-Element hast, dann nicht.