# Verkettete Liste



## Googlehupf (21. April 2012)

Hallo,

wir lernen gerade Verkettete Listen und ich bin mir nicht ganz im Klaren wie das genau funktioniert.

Im Grunde kann das Programm: Spielzüge von Ticatactoe auslesen aus einem Binärfile(x-position, y-position und zeichen).

In den comments steht alles.

h-file:

```
struct spielzug_struct
{
  int posx;
  int posy;
  char zeichen;
	struct spielzug_struct * next;//dieser pointer zeigt auf das nächste element
	struct spielzug_struct * prev;//dieser pointer zeigr auf das vorherige element 
/*aber wie funktioniert das hier genau zeigt der pointer jetzt nur auf einen Wert oder auf den ganzen Block/Struktur? Wo sieht man jetzt das der prev-pointer auf den vorheriegen zeigt und next auf den nächsten? Irgendwie hab ich voll das Blackout grad^^*/
};

typedef struct spielzug_struct spielzug;

struct spielzugfile_struct
{
  int posx;
  int posy;
  char zeichen;
};
typedef struct spielzugfile_struct spielzugfile;


void zuege2file(char filename[], spielzug zug);

spielzug * file2zuege(char filename[]);
```

1. c-file

```
#include "spielzuege.h"
#include <stdio.h>
#include <stdlib.h>



void zuege2file(char filename[], spielzug zug)
{
	FILE* infile = NULL;

	infile = fopen(filename,"a+b");
	if(infile == NULL)
	{
		printf("FILE %s counld not be opened!",filename);
		exit(-1);
	}
  
	else
	{
		fwrite(&zug,sizeof(spielzug),1,infile);
	}

	fclose(infile);

	return;
}

spielzug * file2zuege(char filename[])
{
	FILE* infile = NULL;
	spielzug* liste = NULL;
	spielzug* act_spielzug = NULL;
	spielzug* letzer_spielzug = NULL;
	spielzugfile buffer;

	if ( ( infile = fopen(filename,"rb")) != NULL)
	{
    while(fread(&buffer,sizeof(spielzugfile),1,infile) == 1)
		{
			act_spielzug = (spielzug* )malloc(sizeof(spielzug));//warum braucht man hier ein malloc, das es öfter als einmal aufgerufen wird durch die while ja?
			if (act_spielzug == NULL) 
			{
				exit(-1);
			}
			act_spielzug->posx=buffer.posx;//ja hier werden einfach die werte zugeweisen
			act_spielzug->posy=buffer.posy;//dasselbe...
			act_spielzug->zeichen=buffer.zeichen;//dasselbe
			act_spielzug->next=NULL;//warum lässt man hier den next-pointer auf "Nichts" zeigen?
			if (liste == NULL)//wann soll den bitte der pointer liste auf was anderes außér NULL zeigen?
			{
			  liste = act_spielzug;//was bringt das hier?
			}
			else
			{
				letzer_spielzug->next= act_spielzug;//Warum macht man das hier, falls liste != NULL ist?
			}
			letzer_spielzug=act_spielzug;//Und da?

		}

		fclose(infile);
	}
  return liste;//warum übergibt man liste? und net actSpielzug oder so?
}
```

2.c-file(main):

```
#include "spielzuege.h"
#include <stdio.h>
#include <stdlib.h>


int main()
{
  spielzug * alle_zuege = NULL;
	spielzug * zuege_first = NULL;

  zuege_first = file2zuege("zuege.dat");
  alle_zuege=zuege_first;

	while(alle_zuege != NULL)
	{
		printf("x:%d,y:%d,stein:%c\n",alle_zuege->posx,alle_zuege->posy,alle_zuege->zeichen);
		alle_zuege=alle_zuege->next;
	}

	return 0;
}
```

Ja ich weiß sehr viele Frage, unter anderem auch sicher grundlegende, aber ich verstehe das irgendwie nicht. 

Wäre auch aufejdenfall sehr dankbar, wenn ihr mir das erklären könntet.

Danke im voraus! 

Gruß

Googlehupf


----------



## ibafluss (21. April 2012)

Der Sinn solcher Liste ist es, so etwas wie ein dynamisches Array zu erstellen. Die next- und previous-Pointer zeigen beide auf eine Variable vom Typ spielzug_struct, um eine Verkettung zu ermöglichen. Natürlich verkettet die der Compiler nicht selbst, das musst du selbst machen (wegen deiner Frage woran man sieht, dass z.B. next auf das nächste Element zeigt). Die Pointer sind dazu da, dass so eine Liste überhaupt möglich ist.

c-file: 
Zeile 40: Mit malloc() reservierst du dir Speicher für ein neues spielzeug_struct Element. Das neue Element kann dann an die Liste angehängt werden.

Zeile 48: Das neue Element, das angehängt wird, wird ja logischerweise am Ende angehängt. Und am Ende gibt es logischerweise auch kein nächstes Element, deshalb lässt man next auf NULL zeigen.

Zeile 49: liste ist der Zeiger auf den Anfang der Liste. Wenn dieser auf NULL zeigt, bedeutet das, dass die Liste noch leer ist, also keine Element angehängt wurden.

Zeile 51: Wenn die Liste leer ist, soll der Anfangszeiger list natürlich auf das neu erstellte Element zeigen (irgendwo muss man ja anfangen).

Zeile 55: letzter_spielzug ist ein Zeiger auf das letzte Element der Liste. Wenn man ein neues Element erstellt, möchte man das natürlich am Ende der Liste anhängen. Deshalb zeigt das next vom letzten Element jetzt auf das neue letzte Element (für das am Anfang Speicher reserviert wurde). Das macht man nur wenn list != NULL ist, denn wenn list auf NULL zeigt, ist ja keine Liste vorhanden und dann zeigt letzter_spielzug auch nicht auf das letzte Element, weil es ja keins gibt.

Zeile 57: Das neue Element wurde hinten an der Liste angehängt, jetzt muss nur noch letzter_spielzug auf das neue letzte Element zeigen, das wird hier erreicht.

Zeile 63: Zurückgegeben wird ein Zeiger auf den Anfang der Liste. Warum sollte man die Adresse eines Elements der Liste zurückgeben? Mit dem Anfangspointer hast du am leichtesten auf alle Elemente Zugriff.

Ich hoffe ich habe dir ein bisschen Licht in die Sache gebracht 

Lg


----------



## Googlehupf (21. April 2012)

Danke, jup ich sehe eindeutig Licht .

Aber was ich noch nicht ganz begriffen habe, wie funktioniert das genau mit dem next und prev Pointern?

Also wie funktioniert das, das der next pointer von 1. Element auf 2. zeigt und 2. auf 3? Das selbe mit prev nur umgekehrt?

Danke!

Gruß


----------



## sheel (21. April 2012)

Versteh die Frage irgendwie nicht?
Das sind ganz normale Pointer.

Anders als beim Array (bei dem alles genau hintereinander im Speicher ist)
wird bei einer Liste ja jedes Element getrennt angelegt.
Wo gerade Platz ist.
Und weil man nur zB. das erste Element in einer Variable hat
muss man die anderen dann ja irgendwie wiederfinden können.
Deswegen hat jeder Wert die Pointer dabei
(deren Inhalt man beim Anlegen/Einfügen der/in die Liste eben setzen muss).


----------



## Googlehupf (21. April 2012)

Danke!

Mh ok ich versuchs anders zu formulieren:

Der Unterschied zwischen Array und Listen ist ja das die Größe ja vorher nicht bekannt sein muss bei Listen, bei Arrays bzw. normalen Pointer aber schon.

Bei normalen Pointern muss man ja pointer++ machen um auf die nächste addresse zu zeigen also um da den nächsten Wert abspeichern zu können stimmt das oder stehn die Werte alle auf den selben Adressen?

Ja und bei Arrays macht mann einfach x++, also man erhöht den Index des Array um den nächsten Wert dann zu speichern.

Wie funktioniert das dann bei den Listen? In meinem code kann ich nirgends einen Ersatz für "pointer++" erkennen? Also zeigen hier verschiedene Pointer auf verschiedene Werte? Und die Werten stehen dann auf verschiedene Adressen?


----------



## ibafluss (22. April 2012)

Dafür ist ja der next-Zeiger. Es ist ein Zeiger auf das nächste Element in der Liste. Mit pointer++ kannst du bei einem Array auf das nächste Element zugreifen und bei Listen eben auf list->next.

Lg


----------



## Googlehupf (28. April 2012)

Ich hab mir mein Programm etwas näher angeschaut, d.h. ich bin mit Einzelschritt durchgegangen und hab folgendes festgestellt:

Beim 1. While durchgang geht "es" in die if rein, da noch keine spielzüge da sind.

Beim 2. While durchgang, geht "es" statt in die if in die else(Zeile 49) und kopiert act_spielzug zu letzter_spielzug->next und wenn ich dann unten schaue, im visual c, da wo die ganzen variable steht, hat nun auch liste->next den gleichen Wert wie letzter_spielzug->next.

Beim 3. While durchgang, geht "es" wieder in die else, kopoiert act_spielzug zu letzter_spielzug->next und das was in letzter_spielzug->next steht, steht jetzt nun auch in liste->next->next... Also es entsteht nun eine "verkettung" bzw. es ist verschachtelt. 

Wieso ist dann in list->next automatisch die gleiche Adresse wie in letzter_spielzug->next?


----------



## ibafluss (29. April 2012)

letzter_spielzug zeigt, wie er Name schon sagt auf das letzte Element der Liste. list zeigt auf den Anfang der Liste. 
Am Ende des 1. Durchlaufes zeigen list und letzter_spielzug auf dasselbe Element (weil es nur eins gibt und das zugleich das erste und letzte ist). 
Am Ende des 2. Durchlaufes wird ein Element angehängt, das bedeutet list zeigt natürlich noch immer auf den Anfang und letzter_spielzug zeigt auf list->next. 
Am Ende des 3. Durchlaufes kommt wieder ein Element dazu, das bedeutet list zeigt natürlich noch immer auf den Anfang und letzter_spielzug zeigt auf list->next->next.

So geht das immer weiter, ich hoffe ich habe deine Frage richtig verstanden. Versuch einmal dir das alles aufzuzeichnen, also die liste und wie das verkettet ist, das mach ich auch immer und mir hilft es ziemlich gut.

Lg


----------



## Googlehupf (20. Mai 2012)

Danke! Ich habs jetzt verstanden! 

Wir sollen nun einen einen Spielzug irgendwo in die Liste einfügen. Dazu soll ein Pointer auf einen Spielzug zeigen und vor dem darauf gezeigten Spielzug wird dann der Spielzug eingefügt.

Nur wie kann ich den pointer "steuern"? Ich mein wie kann der "Kunde" dem Pointer sagen, dass er auf den 2. Spielzug der Kette zeigen soll, damit ich den neuen dann davor einfügen kann?

Soll ich die Spielzüge durchnummerieren und der "Kunde" gibt dann eine Zahl ein: 2 --> und ich gehe dann mit einer schleife bis 2. Spielzug und lasse dann den Pointer dahin zeigen?

War das so gemeint, oder was haltet ihr davon? Wie würde es man sonst machen?


----------



## ibafluss (20. Mai 2012)

Wenn die Züge nicht sortiert in der Liste vorkommen sollten und der Kunde entscheidet, wo er den Zug einfügen möchte, ist deine Idee sicher eine gute Möglichkeit. Geht so sicher am besten.

Lg


----------



## Googlehupf (20. Mai 2012)

Danke!

Der Lehrer sagte wie sollen das folgende Unterprogramm fertigstellen, da es so noch nicht ganz funktioniert:

Zeile 30-34 fügen ja den neuen Spielzug ein. 
Aber Zeile 37-39 macht ja alles kaputt wieder oder?
Was soll man damit bezwecken?


```
spielzug* insert_before(spielzug * liste, spielzug * element_before, spielzugfile * neuer_zug)
{
	spielzug* act_spielzug = NULL;

	if (element_before == NULL)
	{
		fprintf(stderr,"element position impossible(NULL)!");
		return(liste);
	}

  act_spielzug = (spielzug* )malloc(sizeof(spielzug));
	if (act_spielzug == NULL) 
	{
		exit(-1);
	}

	act_spielzug->posx=neuer_zug->posx;
	act_spielzug->posy=neuer_zug->posy;
	act_spielzug->zeichen=neuer_zug->zeichen;
	act_spielzug->next=NULL;
	act_spielzug->prev=NULL;

	if (liste == NULL)
	{
		liste = act_spielzug;
	}

  else
	{
		act_spielzug->prev=element_before->prev;
    act_spielzug->prev->next= act_spielzug;

		element_before->prev=act_spielzug;
		act_spielzug->next = element_before;

		
		act_spielzug->next = liste;
		liste->prev = act_spielzug;
		liste = act_spielzug;
	}
  return(liste);
}
```


----------



## ibafluss (20. Mai 2012)

Weißt du, was diese Funktion zurückgeben sollte? Also einen Pointer auf das eingefügte Element oder einen Pointer auf den Anfang der Liste oder was? Und wird der im main() irgendeinem Pointer zugewiesen? Könntest du vielleicht mal einen Aufruf im main() zeigen?

Lg


----------



## Googlehupf (20. Mai 2012)

Das Blöde ist es ist noch nicht aufgerufen und ich würde sagen es wird der 1. Spielzug zurückgegeben.

spielzug * liste wird übergeben --> 1. element.

Aber das alles ergibt dann keinen Sinn....


----------



## ibafluss (20. Mai 2012)

Aber du hast Recht, die letzten 3 Zuweisungen sind wirklich nutzlos. Wenn du sie weglässt sollte alles funktionieren. 
Du sagtest bei deinem Post, dass ihr noch etwas ändern müsst, weil noch nicht alles funktioniert. Was funktioniert denn noch nicht?

Lg


----------



## Googlehupf (20. Mai 2012)

Ah jetzt fällt es mir wieder ein 

Es kann ja auch passieren das der Kunde den Spielzug vor dem 1. einfügen will, und das machen die 3 Zeilen oder?

Jetzt muss ich nur noch schaun das ich die Zeilen getrennt behandle...


----------



## ibafluss (20. Mai 2012)

Ja, dass würde Sinn ergeben. 
Da brauchst du nur ein einfaches if() und dann sollte die Funktion funktionieren.

Lg


----------



## Googlehupf (26. Mai 2012)

Hallo,

ich versuche gerade hinzubekommen wie man bei einer doppelt Verketteten Liste Elemente vertauscht.
Den Algorithmos für das vertauschen müsste ich schon haben, aber da gibt es ja Sonderfälle, die ich im Programm zeige.
Da muss ich dann in meinem Fall 5mal den gleichen Code-Vertausch-Abschnitt benutzen oder?
Kann man das nicht einfacher machen?

Wenn so ein Sonderfall eintritt, dann kann ich den unteren Teil des geposteten Codes vergessen, da ich nämlich das element bevor change1/2 oder danach sichere --> wenn aber change 1=1. element, dann ist in dem Fall before1=NULL und before1->next=temp, kann ich dann net machen. 


```
spielzug* change_pointer(spielzug* liste, spielzug* change1, spielzug* change2) //liste zeigt auf das 1. Element der Kette, change1 zeigt auf das element in der kette das mit einen anderen Element in der kette, wo change2 draufzeigt, vertauscht werden muss
{
  spielzug* after1 = NULL;//element nach change1
  spielzug* before1 = NULL;//element bevor change1
	spielzug* after2 = NULL;//element nach change2
  spielzug* before2 = NULL;//element bevor change2
	spielzug* temp = NULL;//pointer zum zwischenspeichern von change2
	
  //4 Sonderfälle:
	if(change1->next == NULL)//es kann ja sein das change1 auf das letzte Element zeigt --> es gibt kein element danach
	{
	  before1=change1->prev;
	}

	if(change2->next == NULL)//es kann ja sein das change1 auf das letzte Element zeigt --> es gibt kein element danach
	{
	  before2=change1->prev;
	}

	if(change1->prev == NULL)//es kann ja sein das change1 auf das erste Element zeigt --> es gibt kein vorheriges Element
	{
	  after1=change1->next;
	}

	if(change2->prev == NULL)//es kann ja sein das change2 auf das erste Element zeigt --> es gibt kein vorheriges Element
	{
	  after2=change1->next;
	}

  /* hier wird zwischen gespeichert, da später das verloren geht */
  before1 = change1->prev;
	after1 = change1->next;
	before2 = change2->prev;
	after2 = change2->next;
	temp=change2;

	//von hier 
  before2->next = change1;
	change1->prev = before2;
	change1-next = after2;
	after2->prev = change1;
	
	before1->next = temp;
	temp->prev = before1;
	temp->next = after1;
	after1->prev = temp;
  // bis hier, werden die Elemente vertauscht also wenn Change 1/2 nicht auf den ersten oder letzten wert der kette zeigen


	return();
}
```

Gruß


----------



## Matthias Reitinger (26. Mai 2012)

Hallo,

so sollte es klappen (ungetestet):


```
spielzug* change_pointer(spielzug* liste, spielzug* change1, spielzug* change2)
{
    spielzug* temp;

    if (change1 == change2) {
        // Sonderfall: nichts zu tun bei selbem Element
        return liste;
    }

    // Nachbarn tauschen
    temp = change1->next;
    change1->next = change2->next;
    change2->next = temp;

    temp = change1->prev;
    change1->prev = change2->prev;
    change2->prev = temp;

    // Neue Nachbarn informieren
    if (change1->next) {
        change1->next->prev = change1;
    }
    if (change1->prev) {
        change1->prev->next = change1;
    }

    if (change2->next) {
        change2->next->prev = change2;
    }
    if (change2->prev) {
        change2->prev->next = change2;
    }

    // Neuen Kopf der Liste ermitteln
    if (change1->prev == NULL) {
        return change1;
    } else if (change2->prev == NULL) {
        return change2;
    } else {
        return liste;
    }
}
```

Grüße,
Matthias


----------



## Googlehupf (26. Mai 2012)

Das Programm vertauscht nur Nachbarn oder? Die ifs verstehe ich leider nicht. Warum verlgeicht man nix miteinander? "==, <=,> etc."? Was machen den deine ifs?


----------



## Matthias Reitinger (26. Mai 2012)

Googlehupf hat gesagt.:


> Das Programm vertauscht nur Nachbarn oder?


Die Funktion vertauscht die Nachbarn der zu vertauschenden Elemente, womit diese effektiv ihre Position in der doppelt verketteten Liste tauschen. Mach dir am besten mal ein Beispiel auf Stift und Papier und vollziehe nach, was passiert.



Googlehupf hat gesagt.:


> Die ifs verstehe ich leider nicht. Warum verlgeicht man nix miteinander? "==, <=,> etc."? Was machen den deine ifs?


Du kannst dir bei diesen Abfragen ein != NULL hinzudenken, das ist äquivalent.

Grüße,
Matthias


----------



## Googlehupf (26. Mai 2012)

Erstmal danke für deine Mühe das Programm schnell zu schreiben und können wir vielleicht mein Programm auch behandeln, denn ich will wissen wie das mit meiner Möglichkeit auch gehen könnte.

Kannst du mir vielleicht auf die Sprünge helfen wie ich mein Problem umgehen kann oder vereinfachen kann(außer mit deiner methode)?


----------



## Googlehupf (27. Mai 2012)

Soll der Code so aussehn? Mit den viele Ifs und gleichen Codebefehlen mehrfach? Und die 2. if geht er immer rein, weis aber nicht wie ich das verhindern könnte.
Na klar ich könnte eine Variable nehemn und die in der 1. if hochzählen und dann vergleichen in der 2. if ob di variable noch den anfangswert hat, wenn nicht dann nicht reingehn, ansonsten schon. Aber eine elegante Lösung ist das auch nicht.

Ich hab folgende Sonderfälle behandelt: change1=1. Element und change2=1. Element.

Aber es gibt noch 2: change1 = letztes Element und change 2= letztes Element.

Da werden es noch mehr ifs und noch mehr gleicher Befehlcode an verschiedenen Stellen.

Soll das der Sinn sein dahinter?

Wie kann ich das anders lösen? Ich kann mir nicht vorstellen das dies passen würde.


```
spielzug* change_pointer(spielzug* liste, spielzug* change1, spielzug* change2) //liste zeigt auf das 1. Element der Kette, temp1 zeigt auf das element in der kette das mit einen anderen Element in der kette, wo change2 draufzeigt, vertauscht werden muss
{
  spielzug* after1 = NULL;//element nach temp1
  spielzug* before1 = NULL;//element bevor temp1
	spielzug* after2 = NULL;//element nach change2
  spielzug* before2 = NULL;//element bevor change2
	spielzug* temp2 = NULL;//pointer zum zwischenspeichern von change2
	spielzug* temp1 = NULL; //pointer zum zwischenspeichern von change1
	
 
	before1 = change1->prev;
	after1 = change1->next;
	before2 = change2->prev;
	after2 = change2->next;
	temp1=change1;
	temp2=change2;
	
  if(change2->prev == NULL)
	{
    temp2->prev=before1;
		after1->prev=temp2;
		temp2->next=after1;

		temp1->prev=before2;
		temp1->next=after2;
		after2->prev=temp1;
	}

	if(change1->prev == NULL && change2->prev != NULL) // hier geht er immer rein, aber soll nicht rein gehn...
	{
    before2->next = temp1;
	  temp1->prev = before2;
	  temp1->next = after2;
	  after2->prev = temp1;

		temp2->prev=before1;
		temp2->next=after1;
		after1->prev=temp2;
	}
  
	if(change1->prev != NULL || change2 != NULL)
	{
    before2->next = temp1;
	  temp1->prev = before2;
	  temp1->next = after2;
	  after2->prev = temp1;

		
	  before1->next = temp2;
	  temp2->prev = before1;
	  temp2->next = after1;
	  after1->prev = temp2;
	}

	if(change1->prev == NULL)
	{
	  liste=temp1;
	}

	if(change2->prev == NULL)
	{
	  liste=change2;
	}

	return(liste);
}
```


----------



## Matthias Reitinger (27. Mai 2012)

Googlehupf hat gesagt.:


> Wie kann ich das anders lösen? Ich kann mir nicht vorstellen das dies passen würde.


Wie man es anders und ohne explizite Behandlung aller Sonderfälle lösen kann, habe ich dir ja schon gezeigt.

Ich glaube dein Verständnisproblem liegt darin, dass du nicht verstehst, was bei der Kopie eines Zeigers passiert. Ein Zeiger ist lediglich ein Verweis auf eine Speicherstelle, quasi eine Hausnummer. Kopierst du einen Zeiger, verweist die Kopie immer noch auf dieselbe Speicherstelle (die kopierte Hausnummer zeigt immer noch auf dasselbe Haus), und es wird kein Speicher kopiert (kein neues Haus gebaut). Als konkretes Beispiel:


```
int* a = malloc(sizeof(int)); // Neuen Speicher reservieren
int* b = a; // a und b zeigen jetzt auf ein und denselben Speicher, keine Kopie!
*a = 42;
printf("*a=%d *b=%d\n", *a, *b); // Ergibt *a=42 *b=42
*b = 4711;
printf("*a=%d *b=%d\n", *a, *b); // Ergibt *a=4711 *b=4711
```

Wenn du unter diesem Aspekt deinen Code betrachtest, dann wirst du sehen, dass der recht unsinnige Sachen macht. Als Beispiel mal deine erste Sonderfallbehandlung, wobei ich die Variablen durch die rechten Seiten der Zuweisungen ersetzt habe:


```
if(change2->prev == NULL)
{
    change2->prev = change1->prev; // 1. OK
    change1->next->prev = change2; // 2. Was ist, wenn change1->next == NULL?
    change2->next = change1->next; // 3. change2->next wird überschrieben und
                                   //    nirgends gesichert, ist also verloren!
 
    change1->prev = change2->prev; // 4. Sinnlos, da wegen 1. bereits
                                   // change1->prev == change2->prev gilt
    change1->next = change2->next; // 5. Sinnlos, da wegen 2. bereits
                                   // change1->next == change2->next gilt
    change2->next->prev = change1; // Was ist, wenn change2->next == NULL?
}
```

Deine Variablen sind also recht sinnlos und tragen höchstens zur Verwirrung bei.

Mein Rat: mach dir bewusst, wie Zeiger funktionieren, schreib die Funktion von Grund auf komplett neu, verwende keine Hilfsvariablen als „Abkürzung“, kommentiere jeden Codeblock (was willst du damit erreichen), formatiere den Code einheitlich (kein „Flattersatz“ am linken Rand) und dann schauen wir weiter.

Grüße,
Matthias


----------



## Googlehupf (8. Juni 2012)

Ok, danke.

Ich hab jetzt die Fälle behandelt.

Was sagt ihr dazu könnte es so funktionieren?


```
spielzug* change_pointer(spielzug* liste, spielzug* change1, spielzug* change2) //liste zeigt auf das 1. Element der Kette, change1 zeigt auf das element in der kette das mit einen anderen Element in der kette, wo change2 draufzeigt, vertauscht werden muss
{
  spielzug* after1 = NULL;//element nach change1
  spielzug* before1 = NULL;//element bevor change1
	spielzug* after2 = NULL;//element nach change2
  spielzug* before2 = NULL;//element bevor change2
	spielzug* temp = NULL;//pointer zum zwischenspeichern von change2
	
	before1 = change1->prev;//sichern des elements bevor change1
	after1 = change1->next;//sichern des elements nach change1
	before2 = change2->prev;//sichern des elements bevor change2
	after2 = change2->next;//sichern des elements nach change2


	if(before1 == NULL && after2 == NULL)
	{
	  before2->next=change1;
		change1->prev=before2;
		change1->next=NULL;

		after1->prev=change2;
		change2->next=after1;
		change2->prev=NULL;
	}

	if(before2 == NULL && after1 == NULL)
	{
	  before1->next=change2;
		change2->prev=before1;
		change2->next=NULL;

		after2->prev=change1;
		change1->next=after2;
		change1->prev=NULL;
	}

	if(after1 == NULL && before2 != NULL)
	{
	  before1->next=change2;
		change2->prev=before1;
		change2->next=NULL;

		before2->next=change1;
		change1->prev=before2;
		after2->prev=change1;
		change1->next=after2;
	}

	if(after2 == NULL && before1 != NULL)
	{
	  before2->next=change1;
		change1->prev=before2;
		change1->next=NULL;

		before1->next=change2;
		change2->prev=before1;
		after1->prev=change2;
		change2->next=after1;
	}

	if(before1 == NULL && after2 != NULL)//wenn change1 = 1. Elemente --> geht er in die if, sonst nicht.
	{
		/*vertauscht die beiden elemente*/
	  before2->next=change1;
		change1->prev=before2;
		after2->prev=change1;
		change1->next=after2;

		change2->prev=NULL;
		change2->next=after1;
		after1->prev=change2;

		liste=change2;
	}
  
	if(before2 == NULL && after1 != NULL)
	{
		before1->next=change2;
		change2->prev=before1;
		after1->prev=change2;
		change2->next=after1;

		change1->prev=NULL;
		change1->next=after2;
		after2->prev=change1;

		liste=change1;
	}

	if(after1 != NULL && after2 != NULL && before1 != NULL && before2 != NULL)
	{
		/*vertauscht die beiden elemente*/
		before2->next = change1;
		change1->prev = before2;
		change1->next = after2;
		after2->prev = change1;

		before1->next = change1;
		change2->prev = before1;
		change2->next = after1;
		after1->prev = change2;
	}
	return(liste);
}
```


----------



## Googlehupf (17. Juni 2012)

Aber seht euch doch meine Code an, also ich persönlich finde ihn s******, weil es ist viel zu viel Code und im Prinzip spielt sich fast immer das selber ab.

Kann mir den einer nen Tipp bitte geben wie ich das etwas einfacher machen kann?

Danke!


----------



## Matthias Reitinger (17. Juni 2012)

Googlehupf hat gesagt.:


> Kann mir den einer nen Tipp bitte geben wie ich das etwas einfacher machen kann?


Was passt dir denn an [post=2004820]meinem Vorschlag[/post] nicht?

Grüße,
Matthias


----------

