<?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[Liste umdrehen (einfach verkettete)]]></title><description><![CDATA[<p>Hallo, ich möchte gerne die Liste umdrehen, also das erste Element soll nun das letzte sein und das letzte Element das erste.</p>
<p>Es gibt zwar die STL-Funktion aber die wollte ich erstmal nicht benutzen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<pre><code class="language-cpp">const int MAX = 10;

struct Puffer {
  char D[MAX];
  int Anfang, Ende;
};

void leere (Puffer&amp; P) {            // Referenzparameter (wird verändert)
  P.Anfang = P.Ende = 0;
}

boolean istLeer (Puffer P) {        // Wertparameter (wird nur abgefragt)
  return P.Anfang == P.Ende;
}

boolean istVoll (Puffer P) {
  return P.Anfang == (P.Ende + 1) % MAX;
}

void lege (Puffer&amp; P, char c) {     // Einschränkung:
  if (istVoll (P)) return;          // Fehler wird ignoriert!
  P.D[P.Ende++] = c;
  if (P.Ende &gt;= MAX) P.Ende = 0;
}

char entnimm (Puffer&amp; P) {
  if (istLeer (P)) return '\0';     // dto.
  char z = P.D[P.Anfang++];
  if (P.Anfang &gt;= MAX) P.Anfang = 0;
  return z;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/205450/liste-umdrehen-einfach-verkettete</link><generator>RSS for Node</generator><lastBuildDate>Fri, 09 Oct 2026 03:04:22 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/205450.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 14 Feb 2008 12:46:23 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Liste umdrehen (einfach verkettete) on Thu, 14 Feb 2008 12:46:23 GMT]]></title><description><![CDATA[<p>Hallo, ich möchte gerne die Liste umdrehen, also das erste Element soll nun das letzte sein und das letzte Element das erste.</p>
<p>Es gibt zwar die STL-Funktion aber die wollte ich erstmal nicht benutzen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<pre><code class="language-cpp">const int MAX = 10;

struct Puffer {
  char D[MAX];
  int Anfang, Ende;
};

void leere (Puffer&amp; P) {            // Referenzparameter (wird verändert)
  P.Anfang = P.Ende = 0;
}

boolean istLeer (Puffer P) {        // Wertparameter (wird nur abgefragt)
  return P.Anfang == P.Ende;
}

boolean istVoll (Puffer P) {
  return P.Anfang == (P.Ende + 1) % MAX;
}

void lege (Puffer&amp; P, char c) {     // Einschränkung:
  if (istVoll (P)) return;          // Fehler wird ignoriert!
  P.D[P.Ende++] = c;
  if (P.Ende &gt;= MAX) P.Ende = 0;
}

char entnimm (Puffer&amp; P) {
  if (istLeer (P)) return '\0';     // dto.
  char z = P.D[P.Anfang++];
  if (P.Anfang &gt;= MAX) P.Anfang = 0;
  return z;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1455810</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1455810</guid><dc:creator><![CDATA[MarcR]]></dc:creator><pubDate>Thu, 14 Feb 2008 12:46:23 GMT</pubDate></item><item><title><![CDATA[Reply to Liste umdrehen (einfach verkettete) on Thu, 14 Feb 2008 12:51:43 GMT]]></title><description><![CDATA[<p>Öh, und wo ist nun die einfach verkettete Liste?!? Oder willst Du den C-String umdrehen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1455816</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1455816</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Thu, 14 Feb 2008 12:51:43 GMT</pubDate></item><item><title><![CDATA[Reply to Liste umdrehen (einfach verkettete) on Thu, 14 Feb 2008 13:02:06 GMT]]></title><description><![CDATA[<p>also die Anordnung der Elemente des Puffers sind in einem Vektor der Länge MAX, das ist richtig. ^^ Nun möchte wollte ich zusätzlich noch eine funktion schreiben die diese Liste halt umdreht, und zwar so das die einzelnen Elemente des vektors vertauscht werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1455824</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1455824</guid><dc:creator><![CDATA[MarcR]]></dc:creator><pubDate>Thu, 14 Feb 2008 13:02:06 GMT</pubDate></item><item><title><![CDATA[Reply to Liste umdrehen (einfach verkettete) on Thu, 14 Feb 2008 13:44:58 GMT]]></title><description><![CDATA[<p>Gut:</p>
<p>du musst halt anfangen auf eine Lösungsidee zu kommen.</p>
<p>Also du könntest sagen: ok ich vertausch immer die 2 aneinanderliegenden:</p>
<p>a-&gt;b = b-&gt;a</p>
<p>geht hier aber nicht mehr:</p>
<p>a-&gt;b-&gt;c-&gt;d = d-&gt;a-&gt;b-&gt;c</p>
<p>jetzt könnte man sagen: gut, je mehr elemente desto öfter werd ich das wohl machen müssen.<br />
also muss die anzahl der schleifendurchläufe wohl mit anzahl der listenelemente zusammenhängen.</p>
<p>Übrigends:</p>
<p>ich nehme an die Elemente sollen auch auf die neu angeordneten richtig zeigen.</p>
<p>also aus a-&gt;b-&gt;c-&gt;d wird d-&gt;c-&gt;b-&gt;a richtig?</p>
<p>also könntest du es so machen, dass der pointer auf das nächste element in der vertauschten liste zeigt.</p>
<p>Das ist einmal ein so selbst zusammengefädelter lösungsansatz.<br />
Bin auf deine antwort gespannt.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1455856</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1455856</guid><dc:creator><![CDATA[XaTrIxX]]></dc:creator><pubDate>Thu, 14 Feb 2008 13:44:58 GMT</pubDate></item><item><title><![CDATA[Reply to Liste umdrehen (einfach verkettete) on Thu, 14 Feb 2008 18:46:21 GMT]]></title><description><![CDATA[<p>Hier ist es meines Erachtens sinnvoll, das Problem in zwei Teile zu zerlegen.<br />
1.) es muss eine Möglichkeit geschaffen werden, über alle Elemente des Puffers zu laufen<br />
2.) der eigentliche Algorithmus <em>reverse</em> zum Vertauchen der Reihenfolge der Elemente im Puffer</p>
<p>Zu 1.) eignet sich ein Iterator - etwa so was:</p>
<pre><code class="language-cpp">struct PufferIterator
{
    Puffer* m_puffer;
    int m_idx;
};
</code></pre>
<p>Ein Objekt dieser Struktur zeigt auf genau ein Element in einem Puffer - also in diesem Fall auf m_puffer-&gt;D[m_idx].</p>
<p>Zum Traversieren muss man diesen Iterator hoch- und runterzählen können. Ich mache jetzt mal in dem Stil weiter, wie Du den Puffer aufgebaut hast. Dann ergeben sich zwei Funktionen zum inkrementieren (inc: hochzählen) und Dekrementieren (dec: runterzählen).</p>
<pre><code class="language-cpp">PufferIterator&amp; inc( PufferIterator&amp; pi )
{
    if( ++pi.m_idx &gt;= MAX )
        pi.m_idx = 0;
    return pi;
}
PufferIterator&amp; dec( PufferIterator&amp; pi )
{
    if( pi.m_idx-- == 0 )
        pi.m_idx = MAX-1;
    return pi;
}
</code></pre>
<p>Für den Zugriff auf das aktuelle Element und für den Vergleich zweier Iteratoren - wird im Algorithmus benötigt - braucht man noch einen !=-Operator und das Dereferenzieren (deref) - also den Zugriff auf das aktuelle Element.</p>
<pre><code class="language-cpp">bool operator!=( const PufferIterator&amp; a, const PufferIterator&amp; b )
{
    return a.m_idx != b.m_idx || a.m_puffer != b.m_puffer;
}
char&amp; deref( const PufferIterator&amp; pi )
{
    return pi.m_puffer-&gt;D[ pi.m_idx ];
}
</code></pre>
<p>Das hat bisher zunächst gar nichts mit dem gesuchten Algorithmus zu tun; erleichtert aber dessen Erstellung ganz enorm.</p>
<p>Wegen der besseren Übersichtlichkeit im Code verpasst man dem Iterator noch einen Konstruktor. Dann ändert sich die struct PufferIterator zu:</p>
<pre><code class="language-cpp">struct PufferIterator
{
    PufferIterator( Puffer&amp; P, int idx )
        : m_puffer( &amp;P )
        , m_idx( idx )
    {}
    Puffer* m_puffer;
    int m_idx;
};
</code></pre>
<p>Bevor ich jetzt zu reverse komme, zunächst ein Beispiel, wie der Iterator angewendet wird:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
// Puffer &amp; PufferIterator (s.o.)

int main()
{
    using namespace std;
    Puffer buf;
    leere( buf );   // notwendig, da Default-Konstruktor fehlt

    // --   ein wenig Puffer-Aktion
    for( char c = 'a'; c != 'e'; ++c )
        lege( buf, c );
    while( !istLeer( buf ) )
        entnimm( buf );
    for( char c = '1'; c != '9'; ++c )
        lege( buf, c );

    // --   Puffer ausgeben
    for( PufferIterator i( buf, buf.Anfang ); i != PufferIterator( buf, buf.Ende ); inc( i ) )
        cout &lt;&lt; deref( i );
    cout &lt;&lt; endl;
    return 0;
}
</code></pre>
<p>Man sieht jetzt, dass in der Schleife keine Rücksicht mehr darauf genommen werden muss, dass der interne Index 'm_idx' beim Inkrementieren am Ende des Arrays D[] wieder auf 0 gesetzt werden muss. Dies ist in den Funktionen inc bzw. dec versteckt.</p>
<p>Der Iterator ist zwar nicht Standard-konform <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /> , aber trotzdem ein echter Iterator.</p>
<p>Zu 2.): Der Algorithmus <em>reverse</em> beginnt von beiden Seiten - also Anfang und Ende - und tauscht einfach die Elemente aus, bis die beiden Iteratoren sich in der Mitte treffen.</p>
<pre><code class="language-cpp">void reverse( PufferIterator von, PufferIterator bis )
{
    for( ; von != bis &amp;&amp; von != dec( bis ); inc( von ) )
    {
        // swap( *von, *bis );
        char tmp = deref( von );
        deref( von ) = deref( bis );
        deref( bis ) = tmp;
    }
}
</code></pre>
<p>Der Aufruf ist Dank des Konstruktors von PufferIterator ganz einfach (vor Zeile 18 im main() einfügen):</p>
<pre><code class="language-cpp">// --   Reihenfolge im Puffer 'buf' umdrehen
    reverse( PufferIterator( buf, buf.Anfang ), PufferIterator( buf, buf.Ende ) );
</code></pre>
<p>Das, was Du programmierst hast, ist übrigens keine Liste sondern eine <a href="http://de.wikipedia.org/wiki/Warteschlange_%28Datenstruktur%29" rel="nofollow">Queue bzw. Pipe</a>. Das <em>leere</em> heißt <em>clear()</em>, <em>istLeer</em> ist <em>empty()</em>, <em>lege</em> heißt <em>push()</em> bzw. <em>push_back()</em> und <em>entnimm</em> heißt <em>pop()</em> bzw. <em>pop_front()</em> bzw. der Zugriff auf das erste Element heißt <em>top()</em> bzw. <em>front()</em>.</p>
<p>Noch ein Tipp: mache die Konstante MAX zu einer statischen Variablen in der Klasse Puffer.</p>
<p>Gruß<br />
Werner</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1456062</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1456062</guid><dc:creator><![CDATA[Werner Salomon]]></dc:creator><pubDate>Thu, 14 Feb 2008 18:46:21 GMT</pubDate></item></channel></rss>