Verkettete Listen

coolindu

Grünschnabel
Hallo an alle,
ich stehe vor einem großem Problem. Ich bin Anfänger in C++ und arbeite schon seit sehr sehr langer Zeit an zwei Aufgaben, die euch sicherlich bekannt vorkommen, denn im Forum fand ich die Frage schon mehrmals, aber nicht in reinem C++. Ich habe schon das ganze Internet durchsucht, jedoch fand ich nichts was C++ auch nur ähnelt. Vielleicht fand ich den einen oder anderen Quelltext in C# oder C++/CLI und habe auch versucht den Quelltext entsprechend bei mir anzuwenden. (also Syntax etc geändert) Jedoch erfolglos. Deshalb bin ich hier und hoffe ihr könnt mir helfen.

Zunächst einmal soll ich in der Funktion anhaengen() einen Zeiger anwenden, der immer auf das Ende der Liste zeigt, sodass das Ende nicht bei jedem anhängen neu ermittelt werden muss. Als Hilfestellung ist gegeben, listenanfang durch listenende in der Funktion anhaengen(), als Argument zu ersetzen.

Als nächstes soll ich aus der einfach verketteten Liste eine doppelt verkettete Liste machen und die Liste um eine Funktion erweitern, die es ermöglicht die Liste rückwärts auszugeben.


großen Dank im vorraus




C++:
/* ##################################
Verkettete Liste
###################################*/
#include <iostream>
using namespace std;


//Die Struktur für die Listenelemente
struct listenelement
{
  string daten;
  listenelement* next;
};


//Eine Funktion zum Anhängen von Elementen an die Liste
void anhaengen(string datenneu, listenelement* listenanfang)
{
 //ein lokaler Hilfszeiger, um in der Liste wandern zu können
  listenelement* hilfszeiger;
 //den Hilfszeiger an den Anfang der Liste setzen
  hilfszeiger = listenanfang;
 //Durch die Liste gehen, bis das letzte Element erreicht ist
 while (hilfszeiger->next != NULL)
    hilfszeiger = hilfszeiger->next;
 //ein neues Element an das Ende der Liste anhängen
  hilfszeiger->next = new(listenelement);
 //den Hilfszeiger auf das neue Element setzen
  hilfszeiger = hilfszeiger->next;
 //die Daten in das neue Element eintragen
  hilfszeiger->daten = datenneu;
 //es gibt keinen Nachfolger, daher wird next auf NULL gesetzt
  hilfszeiger->next = NULL;
}


//Eine Funktion zum Ausgeben aller Elemente
void ausgeben(listenelement *listenanfang)
{
 //Ein lokaler Hilfszeiger, um in der Liste wandern zu können
  listenelement* hilfszeiger;
 //den Hilfszeiger auf den Anfang der Liste setzen
  hilfszeiger = listenanfang;
 //das erste Element ausgeben
 cout << hilfszeiger->daten << '\n';
 //Solange das Ende der Liste noch nicht erreicht ist:
 while (hilfszeiger->next != NULL)
 {
   //den Hilfszeiger hilfszeiger auf das nächste Element setzen
    hilfszeiger = hilfszeiger->next;
   //Daten ausgeben
   cout << hilfszeiger->daten << '\n';
 }
}


//die Liste leeren und Speicher freigeben
void ende(listenelement* listenanfang)
{
 //Ein lokaler Hilfszeiger, um in der Liste wandern zu können
  listenelement* hilfszeiger;
 //Solange noch Elemente in der Liste sind
 while (listenanfang != NULL)
 {
   //den Hilfszeiger auf das erste Element der Liste
    hilfszeiger = listenanfang;
   //den Zeiger für den Listenanfang auf das nächste Element setzen
    listenanfang = listenanfang->next;
   //den Speicher für das herausgenommene Element freigeben
   delete(hilfszeiger);
 }
}


int main ()
{
 //ein Zeiger auf den Anfang der Liste
  listenelement* listenanfang;
 //das erste Element erzeugen
  listenanfang = new(listenelement);
 //Daten in das erste Element schreiben
  listenanfang->next = NULL;
  listenanfang->daten = "Element 1";


 //und jetzt weitere Elemente erzeugen
  anhaengen("Element 2", listenanfang);
  anhaengen("Element 3", listenanfang);
  anhaengen("Element 4", listenanfang);


 //die Liste ausgeben
  ausgeben(listenanfang);
 //die Liste wieder abbauen
  ende(listenanfang);


 return 0;
}
 
Hi und Willkommen bei tutorials.de,

ein paar Gegenfragen/Hinweise:

Funktioniert der derzeitige Code?

Bei der ersten Aufgabe soll man der Funktion also Anfang und Ende übergeben, oder versteh ich das falsch?

Sind die Funktionsköpfe (also zB. "void anhaengen(string datenneu, listenelement* listenanfang)")
so vorgegeben oder dürfen sie geändert werden (mehr ändern als den Listenendparameter dazutun)?
anhaengen könnte nämlich auch die Erzeugung vom ganz ersten Element übernehmen,
statt das extra im main zu machen.

Vllt. solltest du "ende" ümbenennen. Wenn man den Code das erste Mal sieht denkt
man evt. zuerst "da wird das Listenende gesucht" statt der Aufräumarbeit.
"loesche" oder so.

PS: Du findest VerketteteListen-Beispiele in C++CLI, aber nicht in C++? :eek:
Dabei sollte es von letzterem viel mehr geben :)
 
Also der Code oben ist der Originaltext, der funktioniert. Für die erste Aufgabe steht ja schon als Hilfestellung dabei die zwei Zeiger zu ändern.
D.h. ich soll nicht mehr den Anfang, sondern nur noch das Ende angeben.
Was die Funktionsköpfe angeht, darf ich nur listenanfang durch listenende austauschen.
Natürlich könnte man das erste Element auch gleich in die Funktion anhaengen() mit hineinnehmen, muss aber leider in der main stehen bleiben.
Was das "ende" angeht, gib ich dir Recht, das kann man noch umbenennen in etwas anderes.

Ich hoffe, ich konnte soweit alle Fragen beantworten.

Viele Grüße

coolindu
 
Hallo coollindu

Ich sehe dafür zwei mögliche Gründe:
1. Die Aufgabe ist irgendwie merkwürdig. Du sollst das listenende in der Funktion anhängen speichern? Wo denn? Als statische Variable? Da schauderts mir im ganzen Körper. Als Parameter? Das wär zu einfach.

2. Du beschreibst zwar was deine Aufgaben sind und wie der Ausgangscode der Aufgabe ist, allerdings ist offenbar bisher kein Ansatz von dir zu finden. Fragen der Form "Ich habe Aufgabe X, wie mache ich das?" bekommen in der Regel nur wenig Feedback. Im Netz gibt es genügend Informationen zu (doppelt-) verketteten Listen, das sollte reichen um mal einen ersten Entwurf selber zu probieren und dann mit konkreten Problemen sich hier zu melden.

Viele Grüsse
Cromon
 

Neue Beiträge

Zurück