C++ einfach Verkettete Liste - Objekte einfügen

T

traknoxx

Hallo,

ich bin C++ Schüler und komme bei einer Aufgabe die ich lösen soll nicht weiter.
Vielleicht kann mir hier jemand helfen, wäre für alle Tipps dankbar!

hier zunächst der Ausgangs-Quellcode:

/* #################################################
Eine einfach verkettete Liste mit Objekten
################################################# */

#include "stdafx.h"

using namespace System;

ref class listenelement {
String ^daten;
listenelement ^next;
public:
void datenSetzen(String ^datenneu);
void einfuegen(String ^datenneu);
void ausgeben();
};

//die Zeichenkette in das Element schreiben
void listenelement::datenSetzen(String ^datenneu) {
daten=datenneu;
}

//neues Element am Ende der Liste einfügen
void listenelement::einfuegen(String ^datenneu) {
//hat next den Wert nullptr?
//dann ein neues Element einfügen
if (next == nullptr) {
next = gcnew listenelement;
next->daten=datenneu;
//nullptr wird automatisch zugewiesen!
}
//sonst die Methode für next noch einmal aufrufen
else
next->einfuegen(datenneu);
//nur zur Veranschaulichung
Console::WriteLine("Daten {0} wurden eingefügt.",datenneu);
}

//Alle Elemente der Liste ausgeben
void listenelement::ausgeben() {
//den ersten Eintrag ausgeben
Console::WriteLine("{0}",daten);
//wenn das Ende nicht erreicht ist, die Methode für next erneut aufrufen
if (next != nullptr)
next->ausgeben();
}

int main(array<System::String ^> ^args)
{
//Handle auf den Anfang der Liste
listenelement ^liste;

//das erste Element per Hand erzeugen
liste = gcnew listenelement;
//Zeichenkette in das erste Element schreiben
liste->datenSetzen("Element 0");

//in einer Schleife mehrere Elemente einfügen
for (Int32 schleife=1;schleife<3;schleife++)
liste->einfuegen("Element "+schleife);

//die Liste ausgeben
liste->ausgeben();

return 0;
}


und hier die Aufgabenstellung:

Erweitern Sie die einfach verkettete Liste mit den Objekten so, dass das Listenende beim Einfügen nicht immer wieder neu ermittelt werden muss, sondern neue Elemente direkt am Ende der Liste eingefügt werden können.

Hilfestellungen:

-Keine Änderungen an der Klasse selbst
-Sie müssen neben dem Anfang der Liste nun auch das Ende der Liste in einem Handle speichern können.
-Setzten Sie den Handle nach dem Einfügen neuer Elemente jeweils auf das aktuelle Ende der Liste.


nun mein Lösungsansatz:


#include "stdafx.h"

using namespace System;

ref class listenelement {
String ^daten;
listenelement ^next;
public:
void datenSetzen(String ^datenneu);
void einfuegen(String ^datenneu);
void ausgeben();
};

//die Zeichenkette in das Element schreiben
void listenelement::datenSetzen(String ^datenneu) {
daten=datenneu;
}

//neues Element am Ende der Liste einfügen
void listenelement::einfuegen(String ^datenneu) {


//ein neues Element einfügen
next = gcnew listenelement;

//Zeichenkette im neuen Element eintragen
next->daten=datenneu;
//nullptr wird automatisch zugewiesen!


//nur zur Veranschaulichung
Console::WriteLine("Daten {0} wurden eingefügt.",datenneu);

}

//Alle Elemente der Liste ausgeben
void listenelement::ausgeben() {
//den ersten Eintrag ausgeben
Console::WriteLine("{0}",daten);
//wenn das Ende nicht erreicht ist, die Methode für next erneut aufrufen
if (next != nullptr)
next->ausgeben();
}

int main(array<System::String ^> ^args)
{
//Handle auf den Anfang der Liste
listenelement ^listenAnfang;

//Handle auf das Ende der Liste
listenelement ^listenEnde;


//das erste Element per Hand erzeugen
listenAnfang = gcnew listenelement;
//Zeichenkette in das erste Element schreiben
listenAnfang->datenSetzen("Element 0");

//Default Listenende
listenEnde = listenAnfang;


//in einer Schleife mehrere Elemente einfügen
for (Int32 schleife=1;schleife<3;schleife++)
listenEnde->einfuegen("Element "+schleife);

//die Liste ausgeben
listenAnfang->ausgeben();

return 0;
}

Leider funktioniert das so noch nicht so wie es eingentlich sollte :-(
Ich denke dass das Problem in der Main-Funktion ist, aber ich komme einfach nicht dahinter.

Wäre sehr dankbar für hilfreiche Tipps...

Danke schon mal für eure Mühe

Grüß traknoxx
 
Postemal alles in COde Tags dann hab ich vielleicht bock mir das anzusehen
[ CODE][/CODE ] Ohne die Leerzeichen. Aber was ich so gesehen habe ist deine Klasse total absurd wenn da das Listenende in der Main setzt mach das doch einfach atomatisch in der EInfüge funktion.
 
Danke schon mal für die schnelle Antwort

Ist hoffe das ist so wie du wolltest?

Code:
/* #################################################

Einsendeaufgabe 6.2

################################################# */

#include "stdafx.h"

using namespace System;

ref class listenelement {
	String ^daten;
	listenelement ^next;
public:
	void datenSetzen(String ^datenneu); 
	void einfuegen(String ^datenneu);
	void ausgeben();
};

//die Zeichenkette in das Element schreiben
void listenelement::datenSetzen(String ^datenneu) {
	daten=datenneu;
}
	
//neues Element am Ende der Liste einfügen
void listenelement::einfuegen(String ^datenneu) {
	
	
	//ein neues Element einfügen
	next = gcnew listenelement;

	//Zeichenkette im neuen Element eintragen
	next->daten=datenneu;
	//nullptr wird automatisch zugewiesen!
	
	//nur zur Veranschaulichung
	Console::WriteLine("Daten {0} wurden eingefügt.",datenneu);
	
}

//Alle Elemente der Liste ausgeben
void listenelement::ausgeben() {
	//den ersten Eintrag ausgeben
	Console::WriteLine("{0}",daten);
	//wenn das Ende nicht erreicht ist, die Methode für next erneut aufrufen
	if (next != nullptr)
		next->ausgeben();
}

int main(array<System::String ^> ^args)
{
	//Handle auf den Anfang der Liste
	listenelement ^listenAnfang;

	//Handle auf das Ende der Liste
	listenelement ^listenEnde;

	//das erste Element per Hand erzeugen
	listenAnfang = gcnew listenelement;
	//Zeichenkette in das erste Element schreiben
	listenAnfang->datenSetzen("Element 0");

	//Default Listenende
	listenEnde = listenAnfang;

	//in einer Schleife mehrere Elemente einfügen
	for (Int32 schleife=1;schleife<3;schleife++) 
		listenEnde->einfuegen("Element "+schleife);

	//die Liste ausgeben
	listenAnfang->ausgeben();

	return 0;
}

wenn ich das Listenende in der Einfüge-Funktion setzen kann ohne die Klasse zu verändern würd ich das schon gern machen, komm nur nicht drauf wie?!
 
Einen wunderschönen guten Morgen,

C++:
int main(array<System::String ^> ^args)
{
	//Handle auf den Anfang der Liste
	listenelement ^listenAnfang;

	//Handle auf das Ende der Liste
	listenelement ^listenEnde;

	//das erste Element per Hand erzeugen
	listenAnfang = gcnew listenelement;
	//Zeichenkette in das erste Element schreiben
	listenAnfang->datenSetzen("Element 0");

	//Default Listenende
	listenEnde = listenAnfang;

	//in einer Schleife mehrere Elemente einfügen
	for (Int32 schleife=1;schleife<3;schleife++) {
		listenEnde->einfuegen("Element "+schleife);
		// --->Hier muss noch das Listenende neu gesetzt werden
	}

	//die Liste ausgeben
	listenAnfang->ausgeben();

	return 0;
}

Du setzt am Anfang das Listenende auf den Listenanfang, was auch richtig ist. Dort bleibt dieser auch. Deine Listenelemente sollten demnach immer am Anfang eingefügt werden. Du musst das Listenende mit jeden neu eingefügten Knoten auf diesen neuen Knoten setzen, da dies ja dein neues Listenende ist.

EDIT: Eventuell muss die Aktualisierung des Listenendes auch in der Funktion einfuegen() geschehen.

Gruss
Mizi
 
Zuletzt bearbeitet:
Guten Morge Mizi Mace,

Danke für die Antwort.

EDIT: Eventuell muss die Aktualisierung des Listenendes auch in der Funktion einfuegen() geschehen.

Das denke ich auch, aber ich weiß nicht wie ich das machen soll ohne der Funktion das aktuelle Listenende zu übergeben bzw. von der Funktion das neue Listenende zurückgeben zu lassen, dafür müsste ich die Methoden der Klasse ändern, und laut Hilfestellung in der Aufgabenstellung sollte das ja nicht nötig sein...

irgendeinen Tipp wie das noch umsetzbar wäre? bin echt schon am verzweifeln :confused:
 
Einen wunderschönen guten Morgen,

innerhalb einer Klasse steht dir das Element als this-Pointer zur Verfügung. In deinem Beispiel rufst die Methode einfuegen() der Klasse listenelement für das Listenelement Listenende auf. Somit kannst du auf das Listenende mit dem this-Pointer zurückgreifen. Du musst dabei aufpassen, dass du die Liste richtig verkettest. Schließlich willst du an das aktuelle Listenende anhängen und erst danach darfst du das Listenende neu setzen.

Gruss
Mizi
 
Zuletzt bearbeitet:
Danke das hört sich schon mal gut an.

Das heißt dann das ich das Listenende nicht an die Funktion übergeben muss sondern
über dem "this-Pointer" darauf zugreifen kann.

also

//ein neues Element einfügen
next = gcnew listenelement;


--------> hier fehlt dann praktisch das setzen auf das neue Listenende oder?
in etwa sowas----> listenEnde = listenEnde->next;

-----> führt aber immer zur Fehlermeldung "error C2065: 'listenEnde': nichtdeklarierter Bezeichner"?!


//Zeichenkette im neuen Element eintragen
next->daten=datenneu;
//nullptr wird automatisch zugewiesen!

Was mach ich hier denn falsch? oder sehe ich vor lauter Bäume den Wald nicht
 
Zuletzt bearbeitet von einem Moderator:
Hi.

Das sieht alles etwas merkwürdig aus. Hast du denn das so vorgegeben bekommen?

Wieso hast du keine Datenstruktur für die Liste wo du den Anfang und das Ende der Liste verwalten kannst?

Das die Methode einfuegen heißt ist auch etwas ungünstig, da mit Einfügen eigentlich nicht Anhängen gemeint ist....

Das Problem was du mit der Methode hast, ist das die Variable welche das Ende der Liste speichert nicht aktuell gehalten werden kann.

C++:
listenEnde->einfuegen("Element "+schleife);
        // --->Hier muss noch das Listenende neu gesetzt werden
Hier müßtest du listenEnde auf das neu angefügte Element setzen. Das ist aber nicht möglich da du an das neu anfügte Element hier nicht herankommst.

Gruß
 
Hi deepthroat,

Ja der ganz oben aufgeführte Ausgangs-Quellcode ist für diese Aufgabe vorgegeben...

listenEnde->einfuegen("Element "+schleife);
// --->Hier muss noch das Listenende neu gesetzt werden


Hier müßtest du listenEnde auf das neu angefügte Element setzen. Das ist aber nicht möglich da du an das neu anfügte Element hier nicht herankommst

Meinst du damit das die Aufgabe so nicht lösbar ist?

Danke für die Mühe

Gruß
 
Zurück