1000 "Knoten" im Heap erstellen, dem letzten Element einen Wert zuweisen

mrs_schokokeks

Grünschnabel
Hi!
Also die Aufgabe lautet in etwas so:

Erstellen Sie folgende Struktur, weisen Sie dem letzten Element 42 zu und geben Sie dieses Element aus.

(Und dann so 'ne verkrüppelte Zeichnung dazu)

Stack Heap

Knoten -----> Knoten-->Knoten-->...Knoten (42)


So wie ich das verstanden habe, muss man 1000 Elemente erstellen, wobei jeder dieser Knoten den nächsten Knoten erstellt (?).

Meiner ersten erbärmlichen Versuche:

Code:
#include <iostream>
using namespace std;

struct Knoten
	{
		Knoten* next;      // hier soll vielleicht noch ein "int wert" hin?
	};


void haengAn(Knoten* &ptr);	


void main ()

{

	Knoten* speicherA = NULL;
	for (int i=1; i<=1000; i++)        // Naja, dass kann ja nicht stimmen... -.-
               {
	haengAn(speicherA);
	}

}

void haengAn(Knoten* &ptr)	 
{
	
	Knoten* temp_ptr;		
	temp_ptr = ptr;			
                if (ptr == NULL)		  
	{
		ptr = new Knoten;	
		ptr->next = NULL;	
	}

	else						 
								  
	while (temp_ptr->next != NULL)         // hier will ich bis zum letzen Element gehen
	{
	               temp_ptr = temp_ptr ->next; 
	}
	
	 temp_ptr->next = new Knoten;        // und diesem letzten Element muss ich 
                                                               // den Wert 42 zuweisen: temp_ptr->next->int = 42?
	temp_ptr->next->next = NULL;
	
}

Dazu muss man sagen, dass ich keine Ahnung habe, was ich da mache und für meine Lösung in der Klausur wurde ich ausgelacht :-(

BITTE BITTE helft mir ^^

Julie
 
Bei der Struktur brauchst du noch ein int (evtl. wäre ein short int besser, weils 1000 Strukturen sind).

Du rufst die Funktion "haengAn" mit einem NULL-Wert auf, das kann nicht stimmen, das sagtest du auch ;)

Und woher weißt du in der Funktion "haengAn", ob "temp_ptr->next->next" 42 ist****
Ich habe mal folgende geschrieben (ungetestet! Keine Haftung für evtl. Zusammenbrüche des PCs):
C++:
typedef unsigned short int TNodeData;

struct TNode
{
  TNode *Next;
  TNodeData *Data;
};

int main()
{
  TNode *Begin = new TNode;
  TNode *CurrentNode = Begin;
  for (int i=0; i<1000; i++)
  {
    CurrentNode->Next = new TNode;
    CurrentNode = CurrentNode->Next;
  }
  CurrentNode->Data = 42;
  
  // Ausgeben
  ...
  
  // Freigeben
  CurrentNode = Begin;
  NodeToDelete = Begin;
  for (;;)
  {
    if (CurrentNode->Next!=NULL)
      CurrentNode = CurrentNode->Next;
    delete NodeToDelete;    
  }
  
  return 0;
}

Edit: Wieso willst du in deiner Funktion "haengAn" zum Ende gehen, woher weißt du ob die Schleife in "main()" fertig ist?
 
Zuletzt bearbeitet:
Keine Haftung für evtl. Zusammenbrüche des PCs ^^ okidoki...
Danke danke!
Ja, die Schleife im main erschien mir sowieso falsch... in einer anderen Aufgabe musste ich sowas ähnliches machen und da musste man auch zum ende gehen und dann = NULL .. Andererseits gabs da auch keine for-Schleife...
Naja, ich probier gleich mal deine Lösung! DANKE!
 
Oh nice! Also ohne "Freigabe" scheint das zu funktionieren. Aber das reicht mir... Danke schön!

Und noch ein paar Verständnisfragen :)

TNode *Begin = new TNode;
TNode *CurrentNode = Begin; // wieso muss immer dieser zweite Pointer erstellt werden?
for (int i=0; i<1000; i++)
{
CurrentNode->Next = new TNode; // hier wird immer der NÄCHSTE Knoten erstellt, oder?
CurrentNode = CurrentNode->Next; //wieso ist diese Zuweisung notwendig?
}


Wie gesagt, in einer anderen Aufgabe wird das so ähnlich gemacht. Da waren noch andere Funktionen zum Löschen und Ausgeben der Inhalte dieser Knoten. Und am Besten wäre das, wenn ich mal das Prinzip verstehen würde ^^
Danke
 
Ja, ich habe auch schon bemerkt, dass das Programm bei der Freigabe abstürzt. Aber ohne Freigabe wird nur der RAM vollgeschrieben und nicht geleert, bis zum nächsten Neustart.

C++:
TNode *Begin = new TNode;   // Dieser Pointer zeigt auf den Anfang des Speicherbereiches
TNode *CurrentNode = Begin; // Dieser Pointer zeigt immer auf das aktuelle Element (zu Beginn gleich wie "Begin", dem Anfang)
for (int i=0; i<1000; i++)  // 1000 verknüpfte Elemente erzeugen
{
  CurrentNode->Next = new TNode;   // Das nächste Element wird erstellt
  CurrentNode = CurrentNode->Next; // Das vorherige erstellte Element wird zum aktuellen
}

Du brauchst "Begin", damit du einen Anfang hast. Sonst weißt du ja nicht bei der Ausgabe, wo der Anfang ist, oder? Du musst dir das so merken "Alles hat einen Anfang" :D

Den zweite Pointer brauchst du, damit du das nächste Element erzeugen kannst.

Die zweite Anweisung in der Schleife brauchst du, damit beim nächsten Schleifendurchlauf nicht wieder auf das gleiche Element zeigst, sondern auf das nächste!

Und am Besten wäre das, wenn ich mal das Prinzip verstehen würde
Wenn du noch Fragen hast, kannst du sie stellen.

Naja, ich probier gleich mal deine Lösung! DANKE!
Aber das reicht mir... Danke schön
Danke
Über ein Betätigen des Danke-Knopfes würde ich mich freuen ;)


PS: Es gibt auch doppelt verkettete Listen. Also bei denen gibt es ein "Prev" und "Next". Da brauchst du nur ein Element, egal welches, anstatt ein Anfang.
 
Ok, ich habs eigentlich verstanden! Uuh, der Danke-Knopf erspart mir die Schreibarbeit :D

Hab gehört, dass man entweder "hinten" oder "vorne" war ranhängen kann an diese Knoten und dass bei dieser Aufgabe das "rückwärts Anhängen" von Vorteil sei. Also dass man wohl beim 1000 Element anfängt.
Ich seh den Vorteil irgendwie darin nicht, ein Unterschied wär ja in der for-Schleif. Also einfach:
for (int i=1000; i>=0; i--) Und sonst?

Und ich überlege grade, wenn die Fragestellung genauso lauten würde, aber dass man z.B. dem 56. Element einen Wert zuweist... Was mach ich dann? Ich kann zwar mit der for-schleife bis zum 56. Wert gehen und dann nach der Zuweisung wieder eine Schleife bis 1000 starten (hoffe ich^^), aber gibt es eine Universallösung, falls ich das mehrmals machen muss?

Und wenn ich z.B. gerade auf einem Knoten "bin" und "rückwärts" gehen will (wenn du das mit doppelt verketteten Listen meinst) und einem vorangegangenen Element einen Wert zuweisen muss, gibt es da eine meinem Niveau entsprechende Möglichkeit? ^^

OK genug gespamt!
 
Hab gehört, dass man entweder "hinten" oder "vorne" war ranhängen kann an diese Knoten und dass bei dieser Aufgabe das "rückwärts Anhängen" von Vorteil sei. Also dass man wohl beim 1000 Element anfängt.
Ich seh den Vorteil irgendwie darin nicht, ein Unterschied wär ja in der for-Schleif. Also einfach:
for (int i=1000; i>=0; i--) Und sonst?
Dazu brauchst du doppelt verketteten Listen:
C++:
struct TNode
{
  TNode *Prev;  // Vorheriges Element
  TNode *Next;  // Nächstes Element
  TNodeData Data; // Daten
};

Sagen wir, du hast ein Element von TNode, das am Ende einer Liste ist. Du willst auf das vorherige Element zugreifen, doch bei der einzeln verketteten Liste klappt das nicht. Da musst du von Anfang an wieder 999 weiter zählen.
Bei der doppelt verketteten Liste kannst du das so machen:
C++:
TNode *End = new TNode;
// ... End ist das Ende einer Liste
TNode *NodeBeforeEnd = End->Prev;   // Vorletztes Element durch "End->Prev" erreichbar

Wie meinst du das mit dem Rückwärts anhängen? Am besten postest du mal die komplette Aufgabenstellung!

Dein Quelltext müsstest du so umschreiben, wenn du 2-Listen verwenden willst:
C++:
int main()
{
  TNode *Begin = new TNode;
  TNode *CurrentNode = Begin;
  for (int i=0; i<1000; i++)
  {
    CurrentNode->Next = new TNode;
    CurrentNode->Next->Prev = CurrentNode;   // Zugriff auf das vorherige Element des oben erstellten neuen Elements
    CurrentNode = CurrentNode->Next;
  }
  CurrentNode->Data = 42;
  delete Begin;  // Du brauchst nur ein Objekt/Element, also entweder Begin oder CurrentNode
  
  return 0;
}
OK genug gespamt!
Wozu sind denn Foren da :D :D?
 
Yay, eigentlich komm ich von allein auf sowas nicht, obwohls soo logisch ist:

CurrentNode->Next->Prev = CurrentNode;

Genau so hab ich das gemeint ^^
Die allererste Aufgabe war mit einer Zeichnung, das kann ich hier schlecht darstellen, aber die hab ich ja verstanden. Die anderen Fragen hab ich mir ausgedacht, wer weiß, was es für kranke Aufgabenstellungen gibt -.-
DANKE
 
CurrentNode->Next->Prev = CurrentNode;
Genau, zuerst greifst du auf das nächste zu, dann wieder auf das vorherige, etwa wie das hier:
Code:
CurrentNode = 1;
CurrentNode->Next = 1+1 = 2;
CurrentNode->Next->Prev = 1+1-1 = 1

Die anderen Fragen hab ich mir ausgedacht, wer weiß, was es für kranke Aufgabenstellungen gibt -.-
:D
Du musst dir das vorstellen, als gäbe es einen Ausgangspunkt (=CurrentNode) und wenn du nach links gehst, ist es Prev und nach rechts Next
 
Zurück