Zum Inhalt springen

Rekursiver Aufruf und Ausgabe dann rückwärts


lempy

Empfohlene Beiträge

Hallo

Bei einem rekursiven Aufruf, ruft eine sich eine Funktion oder Methode selber wieder auf.

Richtig?

Wie aber kann ich einen solchen Aufruf mit Rückwärtsausgabe schreiben?

Noch einmal die verkettete Liste in Klasse:

[code#include "stdafx.h"

using namespace System;

ref class listenelement

{

String ^daten;

listenelement ^next;

listenelement ^ende;

public:

Void setDaten(String ^datenneu);

Void anhaengen(String ^datenneu);

Void ausgeben();

};

Void listenelement::setDaten(String ^datenneu)

{

daten = datenneu;

}

Void listenelement::anhaengen(String ^datenneu)

{

if (next == nullptr)

{

next = gcnew listenelement;

next -> daten = datenneu;

ende = next;

}

else

{

ende -> anhaengen(datenneu);

}

Console::WriteLine("Daten {0} wurden eingfügt.\n",datenneu);

}

Void listenelement::ausgeben()

{

Console::WriteLine("\n{0}",daten);

if (next != nullptr)

next -> ausgeben();

Console::WriteLine("\n\n");

/*if (next != nullptr)

next - next;

next -> ausgeben();*/

}

int main(array<System::String ^> ^args)

{

listenelement ^listenanfang;

listenelement ^listenende;

listenanfang = gcnew listenelement;

listenanfang -> setDaten("Element: 1");

listenende = listenanfang;

for (Int32 schleife = 2; schleife < 4; schleife++)

listenanfang -> anhaengen("Element: " + schleife);

listenanfang -> ausgeben();

listenende -> ausgeben();

Console::WriteLine();

Console::Read();

return 0;

}

]

Bei diesem Versuch gibt mir das Programm das ganze noch mal in 1, 2, 3 aus und so soll es

ja auch nicht sein. Bedingung ist ein Rekursiver Aufruf der Methode ausgeben();

next-- oder --next werden die Minuszeichen mukiert und mit nullptr das selbe.

Im Moment keinen Plan.

Danke

lempy

Link zu diesem Kommentar
Auf anderen Seiten teilen

Sorry.

Mit dem Code-Schnipsel kann ich nichts anfangen. Keine Ahnung was Du mir damit sagen willst.

Klar ist mir, dass die Methode ausgeben() durch nochmaligen Aufruf das ganze Rückwärts ausgeben soll. Dazu verstehe ich Deinen Hinweis nicht.

Gruß

lempy

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 Wochen später...

Hallo flashpixx

Was ist den jetzt genau der Unterschied von Rekursion und Iteration? Habe ich irgendwie nicht wirklich verstanden. Dein Link zur Rekursion bringt mich für mein Programm nicht weiter. Keine Ahnung wie ich das umsetzen soll. Hier noch mal meinen etwas abgeänderten Code, der zwar 3, 2, 1 ausgibt, sondern 3, 2, 3, 3. Vielleicht kannst Du mir einen Tip geben, wie ich in so änder kann das wirklich 3, 2, 1 ausgegeben wird.


#include "stdafx.h"


using namespace System;


ref class listenelement

{

	String ^daten;

	listenelement ^next;

	listenelement ^ende;


public:


	Void setDaten(String ^datenneu);

	Void anhaengen(String ^datenneu);

	Void ausgeben(listenelement ^listenanfang);

	/*Void ausgaberueck(listenelement ^listenede);*/

};


Void listenelement::setDaten(String ^datenneu)

{

	daten = datenneu;

}


Void listenelement::anhaengen(String ^datenneu)

{

	if (next == nullptr)

	{

		next = gcnew listenelement;

		next -> daten = datenneu;


		ende = next;

	}

	else

	{

		ende -> anhaengen(datenneu);

	}


	Console::WriteLine("Daten {0} wurden eingfügt.\n",datenneu);

}



Void listenelement::ausgeben(listenelement ^listenanfang)

{

	Console::WriteLine("{0}",daten);


	if (next != nullptr)


		next -> ausgeben(listenanfang);


	/*ende = next;*/

		if (ende != nullptr)

			ende -> ausgeben(listenanfang);

}


//Void listenelement::ausgaberueck(listenelement ^listenende)

//{

//	Console::WriteLine("{0}",daten);

//

//	if(ende != nullptr)

//	{

//		ende -> ausgaberueck(listenende);

//	}

//}



int main(array<System::String ^> ^args)

{

	listenelement ^listenanfang;

	listenelement ^listenende;


	listenanfang = gcnew listenelement;



	listenanfang -> setDaten("Element: 1");

	listenende = listenanfang;


	for (Int32 schleife = 2; schleife < 4; schleife++)


		listenanfang -> anhaengen("Element: " + schleife);


	listenanfang -> ausgeben(listenanfang);


	/*for (Int32 schleife = 2; schleife < 4; schleife--)


		listenende -> anhaengen("Element: " - schleife);*/


	/*listenende -> ausgaberueck(listenende);*/


	Console::Read();

    return 0;

}


Lieben Dank

lempy

Link zu diesem Kommentar
Auf anderen Seiten teilen

In Deiner Funktion "ausgeben" ist keine Rekursion, sondern eine Iteration!
Natürlich ist das eine Rekursion. Es handelt sich um dieselbe Methode. Das dafür benutzte Objekt ist letztendlich nur ein Parameter, der Unterschied ist rein syntaktischer Natur. Oder wäre es deiner Meinung nach auch keine Rekursion, wenn ausgeben eine freie Funktion oder statische Methode wäre, und das Objekt als Parameter übergeben würde?
Link zu diesem Kommentar
Auf anderen Seiten teilen

Natürlich ist das eine Rekursion

Ich habe hier die Rekursion nur innerhalb des Contextes des Objektes definition, da bei jedem Rekursionsschritt ein anderes Objekt zugrunde liegt, wäre das letztendlich "nur" ein Methodenaufruf des jeweiligen Objektes. Du hast aber Recht, das man letztendlich die Methode mehrfach aufruft und dadurch auf dem Stack der aktuelle Stand gespeichert werden muss und sich nur die Parameter (zugrundeliegendes Objekt) ändert, also so gesehen ist es dann auch eine Rekursion natürlich mit veränderten Parametern

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hey


Hab es geschafft. Das Programm läuft wie es soll. Kann mir jetzt jemand erklären warum es so läuft? Geänderte Stellen habe ich mit Hinweisen versehen.



#include "stdafx.h"


using namespace System;


ref class listenelement

{

	String ^daten;

	listenelement ^next;

	listenelement ^ende;


public:


	Void setDaten(String ^datenneu);

	Void anhaengen(String ^datenneu);

	Void ausgeben();

	Void ausgaberueck();

};


Void listenelement::setDaten(String ^datenneu)

{

	daten = datenneu;

}


Void listenelement::anhaengen(String ^datenneu)

{



	if (next == nullptr)

	{

		next = gcnew listenelement;

		next -> daten = datenneu;


		ende = next;

	}

	else

	{

		ende -> anhaengen(datenneu);

	}


	Console::WriteLine("Daten {0} wurden eingfügt.\n",datenneu);

}



Void listenelement::ausgeben()

{

	Console::WriteLine("{0}",daten);


	if (next != nullptr)


		next -> ausgeben();

}


Void listenelement::ausgaberueck()

{

	Console::WriteLine();


	if(ende != nullptr)


		ende -> ausgaberueck();


	Console::WriteLine("{0}",daten);         [COLOR="green"]// Hier steht die Ausgabe am Ende und es[/COLOR]

}                                                           [COLOR="green"]// Funktioniert!!  Warum?[/COLOR]



int main(array<System::String ^> ^args)

{

	listenelement ^listenanfang;

	listenelement ^listenende;


	listenanfang = gcnew listenelement;



	listenanfang -> setDaten("Element: 1");

	listenende = listenanfang;


	for (Int32 schleife = 2; schleife < 4; schleife++)


		listenanfang -> anhaengen("Element: " + schleife);


	listenanfang -> ausgeben();



	listenende -> ausgaberueck();


	Console::Read();

    return 0;

}


Link zu diesem Kommentar
Auf anderen Seiten teilen

Stell dir das so vor: Jeder Funktionsaufruf bewirkt, dass die Anweisungen, die in der Funktion stehen, auf einen Zettel schreibst und diesen Zettel auf einen Stapel legst.

Wenn du mit einem Zettel fertig bist, nimmst du ihn vom Stapel runter. Du bearbeitest aber immer nur den Zettel, der gerade ganz oben liegt.

Wenn also der erste Aufruf von ausgaberueck passiert, schreibst du auf einen Zettel den Code dieser Methode. Dann arbeitest du ihn ab. Nun steht da drin ein Funktionsaufruf. Das heißt für dich: Neuer Zettel, wieder mit demselben Inhalt. Der vorherige Zettel wird erst einmal nicht weiter bearbeitet. Jeder weitere Aufruf bewirkt, dass ein weiterer Zettel auf dem Stapel landet, bis irgendwann die Bedingung nicht mehr wahr ist. Dann wird der oberste Zettel abgearbeitet, einschließlich der Ausgabe. Damit kann der oberste Zettel entfernt werden. Beim nächsten Zettel geht die Ausführung dann dort weiter, wo sie für den Aufruf unterbrochen wurde. Als nächstes wird also die Ausgabe des Zettels abgearbeitet, der jetzt oben liegt.

Du siehst, dadurch, dass die Ausgabe hinter dem Aufruf steht, geschieht die Ausgabe in umgekehrter Reihenfolge des Aufrufs, weil die Ausgabe erst beim "Abräumen" des Stapels passiert.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hey Klotzkopp

Also ist erste "vorwärts Ausgabe" oder vielmehr die Methode ausgeben() so zu sagen der "Mensch" der mir die Arbeit auf Stapel legt "Bonspiezer". Der fängt natürlich mit der 1 an. Wenn ich dann diesen Stapel weiter bearbeite, dann nehme ich den ersten Zettel für mich runter der für mich als erste Zahl die 3 enthält (rückwärts Ausgabe)?

Lieben Dank

lempy

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...