lempy Geschrieben 27. Mai 2012 Teilen Geschrieben 27. Mai 2012 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 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
flashpixx Geschrieben 27. Mai 2012 Teilen Geschrieben 27. Mai 2012 kleiner Gedanke: dorekursiv { print "vor Rekursion" dorekursiv print "nach Rekursion" } Defakto hast Du hier aber keine Rekursion, denn Du rufst das Ausgaben immer eines anderen Objektes auf, was hier dann einer Iteration entspricht Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
lempy Geschrieben 28. Mai 2012 Autor Teilen Geschrieben 28. Mai 2012 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 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
flashpixx Geschrieben 28. Mai 2012 Teilen Geschrieben 28. Mai 2012 In Deiner Funktion "ausgeben" ist keine Rekursion, sondern eine Iteration! Das Beispiel 1 auf Rekursion ist genau analog zu Deinem Codeausschnitt Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
lempy Geschrieben 7. Juni 2012 Autor Teilen Geschrieben 7. Juni 2012 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 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 8. Juni 2012 Teilen Geschrieben 8. Juni 2012 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? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
flashpixx Geschrieben 8. Juni 2012 Teilen Geschrieben 8. Juni 2012 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 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
lempy Geschrieben 8. Juni 2012 Autor Teilen Geschrieben 8. Juni 2012 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; } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Klotzkopp Geschrieben 8. Juni 2012 Teilen Geschrieben 8. Juni 2012 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. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
lempy Geschrieben 8. Juni 2012 Autor Teilen Geschrieben 8. Juni 2012 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 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
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.