<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Verkettete Listen]]></title><description><![CDATA[<p>Hallo,<br />
ich habe mal eine Frage zu diesem Quelltext (aus C++ von A bis Z):</p>
<pre><code class="language-cpp">// list.cpp
#include &lt;iostream&gt;
using namespace std;
struct Knoten {
   int daten;
   Knoten* next;
};
// Anfang der Liste
Knoten* Anfang = 0;
// Funktionsprototypen
Knoten* insertKnoten( int&amp; val);
void showKnoten( const Knoten* n );
Knoten* deleteKnoten( int dat );
int main(void) {
   Knoten* node;
   int auswahl, ival;
   do {
      cout &lt;&lt; &quot;Eine einfache verkettete Liste\n&quot;;
      cout &lt;&lt; &quot;------------------------------\n&quot;;
      cout &lt;&lt; &quot;-1- Neues Element hinzufügen\n&quot;;
      cout &lt;&lt; &quot;-2- Alle Elemente ausgeben\n&quot;;
      cout &lt;&lt; &quot;-3- Einzelnes Element löschen\n&quot;;
      cout &lt;&lt; &quot;-4- Programm beenden\n\n&quot;;
      cout &lt;&lt; &quot;Ihre Auswahl : &quot;;
      cin &gt;&gt; auswahl;
      switch( auswahl ) {
         case 1 :
            cout &lt;&lt; &quot;Daten eingeben: &quot;;
            cin &gt;&gt; ival;
            node = insertKnoten( ival );
            break;
         case 2:
            showKnoten( node );
            break;
         case 3:
            cout &lt;&lt; &quot;Wert zum Löschen eingeben: &quot;;
            cin &gt;&gt; ival;
            node = deleteKnoten( ival );
            break;
         case 4:
            break;
         default:
            cout &lt;&lt; &quot;Falsche Menüauswahl?\n&quot;;
      }
   }  while( auswahl != 4);
   return 0;
}
// Funktion zum Einfügen neuer Elemente
Knoten* insertKnoten( int&amp; val ) {
   // Ist noch kein Element in der Liste,
   // dann fügen wir das erste am Anfang ein
   if( Anfang == 0 ) {
      Knoten* node = new Knoten;
      node-&gt;daten = val;
      node-&gt;next = 0;
      Anfang = node;
      return Anfang;
   }
   // Es sind bereits Elemente in der Liste,
   // dann soll das neue hinten angehängt werden
   else {
      Knoten* node = Anfang;
      Knoten* newNode;
      while( node-&gt;next != 0 )
         node=node-&gt;next;
      newNode = new Knoten;
      newNode-&gt;daten = val;
      newNode-&gt;next = 0;
      node-&gt;next = newNode;
      return Anfang;
   }
}
// Alle Elemente der Liste anzeigen
void showKnoten( const Knoten* n ) {
   if ( Anfang == 0 ) {
      cout &lt;&lt; &quot;Die Liste ist leer\n&quot;;
   }
   else {
      cout &lt;&lt; &quot;1. Element: &quot; &lt;&lt; n-&gt;daten &lt;&lt; '\n';
      for( int i = 2; n-&gt;next != 0; i++ ) {
         n=n-&gt;next;
         cout &lt;&lt; i &lt;&lt; &quot;. Element: &quot; &lt;&lt; n-&gt;daten &lt;&lt; '\n';
       }
   }
}
// Das erste Element mit dem Wert dat aus der Liste löschen
Knoten* deleteKnoten( int dat ) {
   if ( Anfang == 0 ) {
      cout &lt;&lt; &quot;Die Liste ist leer\n&quot;;
   }
   // Ist das erste Element das von uns gesuchte?
   if( Anfang-&gt;daten == dat ) {
      Knoten* del = Anfang;
      if( Anfang-&gt;next != 0 )
         Anfang = Anfang-&gt;next;
      delete del;
   }
   // Die komplette Liste nach dem gesuchten
   // Element durchlaufen
   else {
     Knoten* node = Anfang;
     while( node-&gt;next != 0 &amp;&amp; node-&gt;next-&gt;daten != dat )
        node=node-&gt;next;
     if( node-&gt;next == 0 )
        cout &lt;&lt; &quot;Element zum Löschen kommt nicht&quot; &lt;&lt;
                &quot; in der Liste vor!\n&quot;;
     else {
        // das zu löschende Element an del zuweisen
        Knoten* del = node-&gt;next;
        // Einen Hilfszeiger hinter das zu löschende Element
        Knoten* help = del-&gt;next;
        // das zu löschende Element &quot;aushängen&quot;
        node-&gt;next = help;
        delete del;
      }
   }
   return Anfang;
}
</code></pre>
<p>Was bringt hier der globale Zeiger node? Er erhält ja von den Funktionen insertKnoten und deleteKnoten nach Ausführung stets den Wert von Anfang zugewiesen. Nur beim Aufruf der Funktion showKnoten wird der Zeiger übergeben. Dort wird er benötigt, da dessen Wert in der Funktion verändert wird. Aber warum wurde da nicht ein lokaler Zeiger verwendet, dem am Anfang der Funktion der Wert von Anfang zugewiesen wurde?<br />
Des weiteren wird bei deleteKnoten, wenn noch keine existiert, nach der Ausgabe, das keiner existiert einfach fortgefahren, was ja jedoch zu einem Absturz führen würde. Muss da nicht noch um den kompletten Rest ein else{}?</p>
<p>Viele Grüße tuxianer</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/249258/verkettete-listen</link><generator>RSS for Node</generator><lastBuildDate>Wed, 16 Sep 2026 15:27:21 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/249258.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 04 Sep 2009 22:14:43 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Verkettete Listen on Fri, 04 Sep 2009 22:19:41 GMT]]></title><description><![CDATA[<p>Hallo,<br />
ich habe mal eine Frage zu diesem Quelltext (aus C++ von A bis Z):</p>
<pre><code class="language-cpp">// list.cpp
#include &lt;iostream&gt;
using namespace std;
struct Knoten {
   int daten;
   Knoten* next;
};
// Anfang der Liste
Knoten* Anfang = 0;
// Funktionsprototypen
Knoten* insertKnoten( int&amp; val);
void showKnoten( const Knoten* n );
Knoten* deleteKnoten( int dat );
int main(void) {
   Knoten* node;
   int auswahl, ival;
   do {
      cout &lt;&lt; &quot;Eine einfache verkettete Liste\n&quot;;
      cout &lt;&lt; &quot;------------------------------\n&quot;;
      cout &lt;&lt; &quot;-1- Neues Element hinzufügen\n&quot;;
      cout &lt;&lt; &quot;-2- Alle Elemente ausgeben\n&quot;;
      cout &lt;&lt; &quot;-3- Einzelnes Element löschen\n&quot;;
      cout &lt;&lt; &quot;-4- Programm beenden\n\n&quot;;
      cout &lt;&lt; &quot;Ihre Auswahl : &quot;;
      cin &gt;&gt; auswahl;
      switch( auswahl ) {
         case 1 :
            cout &lt;&lt; &quot;Daten eingeben: &quot;;
            cin &gt;&gt; ival;
            node = insertKnoten( ival );
            break;
         case 2:
            showKnoten( node );
            break;
         case 3:
            cout &lt;&lt; &quot;Wert zum Löschen eingeben: &quot;;
            cin &gt;&gt; ival;
            node = deleteKnoten( ival );
            break;
         case 4:
            break;
         default:
            cout &lt;&lt; &quot;Falsche Menüauswahl?\n&quot;;
      }
   }  while( auswahl != 4);
   return 0;
}
// Funktion zum Einfügen neuer Elemente
Knoten* insertKnoten( int&amp; val ) {
   // Ist noch kein Element in der Liste,
   // dann fügen wir das erste am Anfang ein
   if( Anfang == 0 ) {
      Knoten* node = new Knoten;
      node-&gt;daten = val;
      node-&gt;next = 0;
      Anfang = node;
      return Anfang;
   }
   // Es sind bereits Elemente in der Liste,
   // dann soll das neue hinten angehängt werden
   else {
      Knoten* node = Anfang;
      Knoten* newNode;
      while( node-&gt;next != 0 )
         node=node-&gt;next;
      newNode = new Knoten;
      newNode-&gt;daten = val;
      newNode-&gt;next = 0;
      node-&gt;next = newNode;
      return Anfang;
   }
}
// Alle Elemente der Liste anzeigen
void showKnoten( const Knoten* n ) {
   if ( Anfang == 0 ) {
      cout &lt;&lt; &quot;Die Liste ist leer\n&quot;;
   }
   else {
      cout &lt;&lt; &quot;1. Element: &quot; &lt;&lt; n-&gt;daten &lt;&lt; '\n';
      for( int i = 2; n-&gt;next != 0; i++ ) {
         n=n-&gt;next;
         cout &lt;&lt; i &lt;&lt; &quot;. Element: &quot; &lt;&lt; n-&gt;daten &lt;&lt; '\n';
       }
   }
}
// Das erste Element mit dem Wert dat aus der Liste löschen
Knoten* deleteKnoten( int dat ) {
   if ( Anfang == 0 ) {
      cout &lt;&lt; &quot;Die Liste ist leer\n&quot;;
   }
   // Ist das erste Element das von uns gesuchte?
   if( Anfang-&gt;daten == dat ) {
      Knoten* del = Anfang;
      if( Anfang-&gt;next != 0 )
         Anfang = Anfang-&gt;next;
      delete del;
   }
   // Die komplette Liste nach dem gesuchten
   // Element durchlaufen
   else {
     Knoten* node = Anfang;
     while( node-&gt;next != 0 &amp;&amp; node-&gt;next-&gt;daten != dat )
        node=node-&gt;next;
     if( node-&gt;next == 0 )
        cout &lt;&lt; &quot;Element zum Löschen kommt nicht&quot; &lt;&lt;
                &quot; in der Liste vor!\n&quot;;
     else {
        // das zu löschende Element an del zuweisen
        Knoten* del = node-&gt;next;
        // Einen Hilfszeiger hinter das zu löschende Element
        Knoten* help = del-&gt;next;
        // das zu löschende Element &quot;aushängen&quot;
        node-&gt;next = help;
        delete del;
      }
   }
   return Anfang;
}
</code></pre>
<p>Was bringt hier der globale Zeiger node? Er erhält ja von den Funktionen insertKnoten und deleteKnoten nach Ausführung stets den Wert von Anfang zugewiesen. Nur beim Aufruf der Funktion showKnoten wird der Zeiger übergeben. Dort wird er benötigt, da dessen Wert in der Funktion verändert wird. Aber warum wurde da nicht ein lokaler Zeiger verwendet, dem am Anfang der Funktion der Wert von Anfang zugewiesen wurde?<br />
Des weiteren wird bei deleteKnoten, wenn noch keine existiert, nach der Ausgabe, das keiner existiert einfach fortgefahren, was ja jedoch zu einem Absturz führen würde. Muss da nicht noch um den kompletten Rest ein else{}?</p>
<p>Viele Grüße tuxianer</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1772489</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1772489</guid><dc:creator><![CDATA[Max123]]></dc:creator><pubDate>Fri, 04 Sep 2009 22:19:41 GMT</pubDate></item><item><title><![CDATA[Reply to Verkettete Listen on Fri, 04 Sep 2009 22:20:08 GMT]]></title><description><![CDATA[<p>Ich vermute, Du solltest das Buch löschen.<br />
node bringt gar nichts. Anfang bringt alles.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1772490</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1772490</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Fri, 04 Sep 2009 22:20:08 GMT</pubDate></item><item><title><![CDATA[Reply to Verkettete Listen on Fri, 04 Sep 2009 22:29:05 GMT]]></title><description><![CDATA[<p>naja ein zweiter Zeiger muss zur Ausgabe schon her,</p>
<pre><code class="language-cpp">n=n-&gt;next;
</code></pre>
<p>hiermit zeigt er ja woanders hin und dann wäre das Anfangselement verloren oder?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1772497</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1772497</guid><dc:creator><![CDATA[Max123]]></dc:creator><pubDate>Fri, 04 Sep 2009 22:29:05 GMT</pubDate></item><item><title><![CDATA[Reply to Verkettete Listen on Fri, 04 Sep 2009 22:33:16 GMT]]></title><description><![CDATA[<p>Max123 schrieb:</p>
<blockquote>
<p>naja ein zweiter Zeiger muss zur Ausgabe schon her,</p>
<pre><code class="language-cpp">n=n-&gt;next;
</code></pre>
<p>hiermit zeigt er ja woanders hin und dann wäre das Anfangselement verloren oder?</p>
</blockquote>
<p>ja, auch ein lokaler del in delKnoten muß sein. die main() muß keine kenntnis der knoten haben, sie muß nichtmal wissen, daß es überhaupt den typ Knoten gibt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1772500</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1772500</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Fri, 04 Sep 2009 22:33:16 GMT</pubDate></item><item><title><![CDATA[Reply to Verkettete Listen on Fri, 04 Sep 2009 23:22:21 GMT]]></title><description><![CDATA[<p>weils schon spät ist, mal etwas umgeschrieben</p>
<pre><code class="language-cpp">// list.cpp
#include &lt;iostream&gt;
using namespace std;
struct Knoten {
   int daten;
   Knoten* next;
};
// Funktionsprototypen
Knoten* letzterKnoten( Knoten* liste );
Knoten* insertKnoten( Knoten* liste, int val);
Knoten* deleteKnoten( Knoten* liste, int val );
void showKnoten( const Knoten* liste );

int main() {
   Knoten* liste = 0;
   int auswahl = 0, ival = 0;
   do {
      cout &lt;&lt; &quot;Eine einfache verkettete Liste\n&quot;
              &quot;------------------------------\n&quot;
              &quot;-1- Neues Element hinzufügen\n&quot;
              &quot;-2- Alle Elemente ausgeben\n&quot;
              &quot;-3- Einzelnes Element löschen\n&quot;
              &quot;-4- Programm beenden\n\n&quot;
              &quot;Ihre Auswahl : &quot;;
      cin &gt;&gt; auswahl;
      switch( auswahl ) {
         case 1 :
            cout &lt;&lt; &quot;Daten eingeben: &quot;;
            cin &gt;&gt; ival;
            liste = insertKnoten( liste, ival );
            break;
         case 2:
            showKnoten( liste );
            break;
         case 3:
            cout &lt;&lt; &quot;Wert zum Löschen eingeben: &quot;;
            cin &gt;&gt; ival;
            liste = deleteKnoten( liste, ival );
            break;
         case 4:
            break;
         default:
            cout &lt;&lt; &quot;Falsche Menüauswahl?\n&quot;;
      }
   }  while( auswahl != 4);
   return 0;
}
// gibt uns das letzte Element einer Liste zurück
Knoten* letzterKnoten( Knoten* liste ) {
   if ( liste != 0 )
      while ( liste-&gt;next != 0 )
         liste = liste-&gt;next;
   return liste;
}
// Funktion zum Einfügen neuer Elemente
Knoten* insertKnoten( Knoten* liste, int val ) {
   Knoten x = { val, 0 };
   // wir fügen einen dummy-Knoten vorne ein, um
   // Sonderfälle zu vermeiden
   // dieser Knoten wird nicht per new angefordert und
   // verschwindet bequemerweise beim Verlassen der Funktion
   Knoten dummy = { 0, liste };
   letzterKnoten( &amp;dummy )-&gt;next = new Knoten( x );
   return dummy.next;
}
// Das erste Element mit dem Wert val aus der Liste löschen
Knoten* deleteKnoten( Knoten* liste, int val ) {
   // wir fügen einen dummy-Knoten vorne ein
   // damit sind keine Sonderfälle mehr zu beachten
   Knoten dummy = { 0, liste };
   Knoten* node = &amp;dummy;
   while( node-&gt;next != 0 &amp;&amp; node-&gt;next-&gt;daten != val )
      node=node-&gt;next;
   if( node-&gt;next == 0 )
      cout &lt;&lt; &quot;Element zum Löschen kommt nicht in der Liste vor!\n&quot;;
   else {
      // das zu löschende Element an del zuweisen
      Knoten* del = node-&gt;next;
      // das zu löschende Element &quot;aushängen&quot;
      node-&gt;next = node-&gt;next-&gt;next;
      delete del;
   }
   return dummy.next;
}
// Alle Elemente der Liste anzeigen
void showKnoten( const Knoten* liste ) {
   if ( liste == 0 ) {
      cout &lt;&lt; &quot;Die Liste ist leer\n&quot;;
   }
   else {
      for( int i = 1; liste != 0; i++ ) {
         cout &lt;&lt; i &lt;&lt; &quot;. Element: &quot; &lt;&lt; liste-&gt;daten &lt;&lt; '\n';
         liste=liste-&gt;next;
       }
   }
}
</code></pre>
<p>Das Löschen des Buches ist wahrscheinlich trotzdem eine gute Idee.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1772510</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1772510</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Fri, 04 Sep 2009 23:22:21 GMT</pubDate></item><item><title><![CDATA[Reply to Verkettete Listen on Sat, 05 Sep 2009 09:16:22 GMT]]></title><description><![CDATA[<p>ok und nochmal ne frage zum Anfangsquelltext. Also man kann die Anfangsposition ja notfalls auch global lassen oder? dann kann man sich aber den kompletten Rückgabewert der Funktion jeweils sparen und node, das in main lokale hat auch keinen Sinn, da man das hätte lokal lösen können.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1772580</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1772580</guid><dc:creator><![CDATA[Max123]]></dc:creator><pubDate>Sat, 05 Sep 2009 09:16:22 GMT</pubDate></item></channel></rss>