Mehrere Elemente aus linearer Liste löschen
-
Hallo zusammen!
Ich habe ein Problem beim Löschen mehrerer Elemente aus einer linearen Liste.
Wenn ich die herauskommentierten Zeilen einfüge, zerlegt es das Programm
und ich habe keine Ahnung warum.(...) struct test *pointer, *pointerTemp; int del1 = 2; /* von Element Nr. 2 */ int del2 = 4; /* bis Element Nr. 4 */ while (pointer->next != NULL) { pointerTemp = pointer->next; while (del1 <= del2) { /* Ausgabe nur zur Kontrolle */ printf("%s: %ld\n", pointer->name, pointer->tel); /* Hier ist irgendwo der Wurm drin */ // pointer->next = pointerTemp->next; // free(pointerTemp); // pointer = pointerTemp; /* Zum nächsten Element weiterschalten */ pointer = pointer->next; del1++; } } (...)
Nachdem ich einen großen Knoten im Hirn habe, bin ich für jeden Ratschlag sehr dankbar.
Viele Grüße,
Planlos.04
-
Planlos.04 schrieb:
// pointer = pointerTemp;
pointerTemp hast du doch gerade gefreet... das kann nicht gut gehen...
-
Danke für diesen Hinweis, aber trotz unzähliger Versuche schaffe ich es leider nicht.
Entweder werden nicht die Elemente gelöscht, die zuvor richtig ausgeben wurden,
oder das Programm stürzt ab. Wahrscheinlich habe ich das Grundprinzip noch nicht verstanden.Die Ausgabe der zu löschenden Elemente funktioniert so fehlerfrei:
(...) while (pointer->next != NULL) { pointerTemp = pointer->next; while (del1 <= del2) { printf("%s: %ld\n", pointer->name, pointer->tel); // Element aushängen, löschen und richtig weiterschalten ??? pointer = pointer->next; del1++; } } (...)
Wenn ich nach printf das richtig angezeigte Element so aushänge und lösche:
pointer->next = pointerTemp->next; free(pointerTemp);
Dann klappt das Weiterschalten mit pointer = pointer->next; nicht mehr.
Vielleicht weiß jemand dafür eine Lösung.
-
vielleicht hilft das:
while(pointer) { Type* temp=pointer; pointer=pointer->next; free(temp); }
Das loescht die gesamte Liste.
-
Ich möchte nicht die gesamte Liste löschen, sondern nur mehrerer Einträge, die hintereinander in der Liste stehen.
Vermutlich bin ich schon etwas weitergekommen, aber der Wurm ist leider nur umgezogen statt ausgezogen.(...) struct test *pointer, *pointerTemp; int del1 = 3; /* von Element Nr. 3 */ int del2 = 4; /* bis Element Nr. 4 */ while (pointer->next != NULL) { pointerTemp = pointer->next; /* Elemente ausgeben und löschen */ while (del1 <= del2) { printf("%s: %ld\n", pointer->name, pointer->tel); pointerTmp = pointer->next; free(pointer); pointer = pointerTmp; del1++; } /* Restlichen Elemente zur Kontrolle ausgeben */ if (start != NULL) { pointer = start; printf("\n"); while (pointer->next != NULL) { printf("%ld\n", pointer->datum); pointer = pointer->next; } } } (...)
Die Ausgabe der restlichen Elemente sollte eigentlich zeigen, dass das Löschen erfolgreich war.
Aber das Programm stürzt bei der Ausgabe des ersten Elements NACH dem gelöschten Bereich ab.Beispiel:
Nach der Löschung der Elemente 3-4, zeigt das Programm die Elemente 1 und 2 korrekt an.
Allerdings gelingt der "Sprung" zum 5. Element nicht und das Programm bleibt stehen.
-
Planlos.04 schrieb:
Nach der Löschung der Elemente 3-4, zeigt das Programm die Elemente 1 und 2 korrekt an.
Allerdings gelingt der "Sprung" zum 5. Element nicht und das Programm bleibt stehen.Weil 2->next auf 3 zeigen wird, welches aber gelöscht ist. du musst 2->next auf 5 zeigen lassen.
-
Shade Of Mine schrieb:
Weil 2->next auf 3 zeigen wird, welches aber gelöscht ist. du musst 2->next auf 5 zeigen lassen.
Danke, das klingt einleuchtend und erklärt die Grundproblematik.
Aber wie kann ich das letzte Element VOR dem Bereich auf das erste Element NACH dem Bereich zeigen lassen?
-
die Problematik mit Listen ist das man die Elemente nicht eindeutig indentifizieren kann wie zB bei einem Array über den Index.
In diesem Fall hilft es Kontrollvariablen einzuführen.zb
struct daten{ void *datenpointer; int *num;//zur kontrolle struct daten *next; struct daten *prev; struct daten *last; }; struct daten *head; void delete_elem(struct daten *head, int num) { //--- if(tmp->num == num) free(tmp); //--- } int add_elem(struct daten *head, struct daten *new_elem) { if(head->last == NULL) //erstes element der liste { new_elem->prev = head; head->last = new_elem; head->next = new_elem; } else { tmp = head->last; tmp->next = new_elem; new_elem->prev = tmp; head->last = new_elem; } }
Sinnvoll ist auch in vielen Fällen doppelt verkette Listen zu benutzen.
der Verwaltungsaufwand ist gering höher aber die Funktionalität der Listen nimmt enorm zu. Auch Sinnvoll ist ein Pointer "last" der auf das letzte Element zeigt.
Hilft zum Beispiel die Liste schnell vom anderen Ende zu traversieren.
Diese Liste ist etwas spezialisiert, aber ich finde man sollte das immer das
beste aus den Möglichkeiten machen die man hat.Das war jetzt zwar keine konkrete Lösung, aber ich hoffe es hilft dir ein bischen besser mit Listen klar zu kommen.
mfg.
-
@Planlos
Das Problem ist, dass du pointerTemp nur vor deiner Schleife auf etwas zeigen lässt. In der Schleife gibst du ja den Speicher auf den pointerTemp zeigt frei und beim nächsten Durchlauf zeigt pointerTemp immer noch auf die gleiche Speicheradresse und nicht, wie wohl gewünscht, auf das nächste zu löschende Element.
-
@ALL:
Hurra, ich habe es endlich geschafft.
Vielen Dank für eure Mithilfe!@sg@gastaccount:
Ich habe bisher noch nichts mit doppelt verketteten Listen programmiert, aber die Vorteile liegen auf der Hand.
Demnächst werde ich versuchen mein Programm entsprechend abzuändern.@AJ
Dein Tipp hat mich auf den richtigen Lösungsweg gebracht. Hierfür ein extra Dankeschön!Viele Grüße,
Planlos.04