# Pointer Tausch



## Scal (31. Januar 2014)

Hallo alle zusammen. Ich und meine Kollegen versuchen schon seit einiger Zeit folgendes Problem zu lösen.
Wir haben eine einfach verkettete Liste. In diesem Beispiel jetzt haben wir 3 Elemente in unserer Liste.

Personlist zeigt auf C.
Personlist -> next zeigt auf B.
Personlist -> next -> next zeigt auf A.

Wir versuchen nun C mit B zu tauschen einfach. Wir haben bereits Hilfpsointer usw. angelegt jedoch funktioniert es nie, meistens endet es damit das wir B verlieren oder in eine Endlosschleife geraten.

Habt ihr einen Tipp wie man am leichtesten und unkompliziertesten C mit B tauschen kann. Quasi einfach die Elemente in der Liste tauschen. Danke für jeden Tipp und eure Hilfe, wir schätzen das wirklich sehr 

liebe Grüße!


----------



## sheel (31. Januar 2014)

Hi

falls ihr die ganzen Knoten (also die ganze struct/class mit next-Pointer)
tauschen (und die Pointer anpassen) wollt:
Bei einer einfach verketteten Liste ist das mindestens umständlich,
weil ihr nicht nur C und C->next (also B) braucht, sondern auch ein D, welches C als next hat,

Eventuell einfacher wäre es, nur die Values von C und B zu tauschen.
Was ist denn der Wert, pro Knoten? Ein int, ein String...?


----------



## deepthroat (31. Januar 2014)

Hi.

So umständlich ist das doch gar nicht.

Man braucht einen Hilfszeiger.


 tmp = B
 C-> next = A
 tmp->next = C
 Personlist = tmp

Evtl. macht ihr auch etwas falsch. Zeigt euren Code.


----------



## sheel (31. Januar 2014)

(sorry, irgendwie schlampig gelesen. Hatte gedacht, C ist das Erste, was man hat)


----------



## Scal (31. Januar 2014)

Das Problem ist, das jedes Element der Kopf einer weiteren Liste ist also Inhalt tauschen geht leider nicht. Aber guter Gedanke! Wir programmieren mit C. 

@deepthroat
Ich habe gerade deine Methode versucht umzusetzen aber wir verlieren dabei A und B. :/ Code zeigen kann ich nicht wirklich da wir ja keinen haben der einigermaßen funktioniert.


----------



## sheel (31. Januar 2014)

Scal hat gesagt.:


> Das Problem ist, das jedes Element der Kopf einer weiteren Liste ist


...also ein einzelner Pointer (auf einen Knoten), oder auch ein Wert und ein Pointer (Knoten selbst).
Das kann man tauschen.


Scal hat gesagt.:


> Code zeigen kann ich nicht wirklich da wir ja keinen haben der einigermaßen funktioniert.


Eben deswegen


----------



## Scal (1. Februar 2014)

Also was ich versucht habe war folgendes:

tmp = Personlist;
tmp_2 = Personlist -> next;

Personlist -> next = tmp;
Personlist = tmp_2;
Person_list -> next -> next = tmp_2 -> next;

Funktioniert leider nicht


----------



## Matthias Reitinger (1. Februar 2014)

Überleg dir einfach mal in Ruhe auf einem Blatt Papier, was dieser Code mit einer Liste von drei Elementen macht. Du kannst z.B. so anfangen:


```
Personlist
  |
  V
+-------+      +-------+      +-------+
| C     |  +-->| B     |  +-->| A     |
| next: *--+   | next: *--+   | next: *--> NULL
+-------+      +-------+      +-------+
  ^              ^
  |              |
 tmp           tmp_2
```

Und dann für jede Anweisung nachvollziehen, wie sich dadurch die Zeiger (Pfeile) ändern. Dann solltest du schnell sehen, was hier schief läuft.

Grüße
Matthias


----------



## Scal (1. Februar 2014)

Danke Matthias  

Also weitere Idee die jedoch in einer Endlosschleife endet:

Personlist = temp -> next;
Personlist -> next -> next = temp2 -> next;
Personlist -> next = temp;

Wieso funktioniert das nicht? :/


----------



## Scal (2. Februar 2014)

Ich überleg nun schon seit in der Früh und es funktioniert einfach nichts. Es is echt frustrierend, wir haben sicher alles probiert was wir für möglich halten aber es geht einfach nicht. Kann eventuell jemand einen Code Hint geben oder etwas in die Richtung? Unsere Deadline rückt näher für das Projekt und das ist der letzte Punkt den wir noch brauchen.

Lg und schönen Sonntag noch!


----------



## sheel (2. Februar 2014)

Noch einmal: Was ist der "value" pro Knoten?
Zeig doch einfach einmal die Struktur her...


----------



## Jennesta (2. Februar 2014)

deepthroat hat dir doch dein Beispiel geliefert. Wenn das nicht funktioniert, dann machst du irgendwas falsch. Aber wie sollen wir den Fehler finden, wenn du nicht einmal den kompletten Code zeigst, der zum Verständnis eurer Lösung hilft?


----------



## Scal (2. Februar 2014)

Den habe ich ja gepostet. Tmp zeigt auf C. Also Temp next zeigt dann ja auf B. Jetzt setze ich Personlist auf temp -> next, also auf B. Danach setze ich Personlist -> next auf temp, das war ja C. Und in der letzen Zeile halt noch das Gleiche. Irgendwo aber verlier ich hier etwas oder es lauft was schief.

Personlist = temp -> next;
Personlist -> next = temp;
Personlist -> next -> next = temp2 -> next;


----------



## sheel (2. Februar 2014)

Jennesta hat gesagt.:


> deepthroat hat dir doch dein Beispiel geliefert. Wenn das nicht funktioniert, dann machst du irgendwas falsch.


Ack


Jennesta hat gesagt.:


> Aber wie sollen wir den Fehler finden, wenn du nicht einmal den kompletten Code zeigst, der zum Verständnis eurer Lösung hilft?


Inzwischen haben drei Leute nach mehr Code gefragt,
weil so nicht geholfen werden kann.


----------



## Scal (2. Februar 2014)

Das ist die Funktion, sort1 und sort2 sind Werte die ich im Moment ausgeblendet habe. 
Die Funktion bekommt PERSON* Person_list. Wir haben ein Struct geschrieben welches immer einen Pointer auf das nächste hat. Das ist der ganze Code der Funktion. 
----------------------------

void sort(PERSON*  Person_list)
{
  PERSON* tmp2 = Person_list;
  PERSON* temp = Person_list->next;

if(sort_1 > sort_2)
{
    printf("Pointertausch\n");

Personlist = temp -> next;
Personlist -> next = temp;
Personlist -> next -> next = temp2 -> next;
x = 999;
 }


----------



## Scal (2. Februar 2014)

Neue Idee die leider auch nicht funktioniert hat:

          tmp->next = tmp_2->next;
          tmp_2->next = tmp;
          Person_list = tmp_2;


----------



## sheel (2. Februar 2014)

So, noch ein mal:
Wenn du uns nur unzusammenhängende Codeschnipsel zeigst,
in denen nicht einmal ein einzelner Variablenname konsistent bleibt,
statt eventuell einmal eine ganze Datei inkl. der Strukturdefinition...
dann _kann dir nicht geholfen werden_.


----------



## Matthias Reitinger (2. Februar 2014)

Scal hat gesagt.:


> Personlist = temp -> next;
> Personlist -> next -> next = temp2 -> next;
> Personlist -> next = temp;
> 
> Wieso funktioniert das nicht? :/


Habt ihr euch das mal auf einem Blatt Papier überlegt? Das Nachvollziehen hätte ich mir in etwa so vorgestellt:


```
Anfangszustand
==============

Personlist
  |
  V
+-------+      +-------+      +-------+
| C     |  +-->| B     |  +-->| A     |
| next: *--+   | next: *--+   | next: *--> NULL
+-------+      +-------+      +-------+
  ^              ^
  |              |
 temp          temp2


Personlist = temp->next;
========================

               Personlist
                 |
                 V
+-------+      +-------+      +-------+
| C     |  +-->| B     |  +-->| A     |
| next: *--+   | next: *--+   | next: *--> NULL
+-------+      +-------+      +-------+
  ^              ^
  |              |
 temp          temp2


Personlist->next->next = temp2->next;
=====================================

               Personlist
                 |              +--------+
                 V              V        |
+-------+      +-------+      +-------+  |
| C     |  +-->| B     |  +-->| A     |  |
| next: *--+   | next: *--+   | next: *--+
+-------+      +-------+      +-------+
  ^              ^
  |              |
 temp          temp2


Personlist->next = temp;
========================

  +-----------------------+
  |            Personlist |
  |              |        |     +--------+
  V              V        |     V        |
+-------+      +-------+  |   +-------+  |
| C     |  +-->| B     |  |   | A     |  |
| next: *--+   | next: *--+   | next: *--+
+-------+      +-------+      +-------+
  ^              ^
  |              |
 temp          temp2
```
Wie du siehst, ist das teils ziemlich unsinnig.

Schlussendlich willst du ja auf diese Konfiguration hinaus:

```
+-----------------------+
  |            Personlist |
  |              |        |
  V              V        |
+-------+      +-------+  |     +-------+
| C     |      | B     |  | +-->| A     |
| next: *--+   | next: *--+ |   | next: *--> NULL
+-------+  |   +-------+    |   +-------+
           +----------------+
```

Mein Tipp: den Rechner ausmachen und sich tatsächlich mal mit einem Blatt Papier hinsetzen und sich in Ruhe überlegen, wie man vorgehen will. Einfach nur alle Permutationen direkt im Quellcode ausprobieren ist nicht zielführend.

Grüße
Matthias


----------



## Scal (2. Februar 2014)

Struktur:

typedef struct _PERSON_{
  char name[20];

  struct _PERSON_* next;
  struct _FRIEND_* Friend_list;
}PERSON;

void sort(PERSON*  Person_list)
{
  PERSON* tmp = Person_list;
  PERSON* tmp_2 = Person_list->next;


int x = 0;  
int sort_1 = 0;
int sort_2 = 0;

while(x < strlen(Person_list->name) && x < strlen(Person_list->next->name))
{
  sort_1 = toupper((int) *(Person_list->name+x));
  sort_2 = toupper((int) *(Person_list->next->name+x));


  if(sort_1 == sort_2)
    {
     x++; 
    }

    else  if(sort_1 > sort_2)
      {

          tmp->next = tmp_2->next;
          tmp_2->next = tmp;
          Person_list = tmp_2;
          x = 999;
          printf("%s\n", Person_list->name);
          printf("%s\n", Person_list->next->name);
          printf("%s\n", Person_list->next->next->name);




      }

      else {
      printf("Passt\n");
      x = 999;}
}
}


----------



## Scal (2. Februar 2014)

Also eine Frage, in der Funktion ändert der Code jetzt so wie er soll und vertauscht C mit B. Jedoch wenn ich dann in der main wieder ein printf mache, dann verliert er B und zeigt wieder C an. 

Die main ruft nur die Funktion auf.


----------



## cwriter (3. Februar 2014)

Bitte Codetags verwenden und Doppelposts vermeiden.

C und B und er zeigt B an? Wie meinen? Wie sieht die main aus? Mit dem erstellten Parameter?
Das mit dem x würde ich überdenken. So wird nämlich nur 1x sortiert...

Gruss
cwriter


----------



## DexXxtrin (7. Februar 2014)

Also wenn ich das richtig sehe, willst du eine Liste von Personen nach deren Namen sortieren?! (unabhängig von Gross-/Kleinschreibung) Wieso machst du das so kompliziert?

Zudem ist logisch, dass beim Aufruf von der Main B fehlt. Du änderst den Pointer nur in der Funktion und nicht in der main. Hab dir mal kurz was geschrieben. Bei mir tuts 


```
#include <stdio.h>
#include <string.h>
#include "main.h"



void main(void){
	PERSON* head;
	PERSON A, B, C;
	
	head = &C;

	A.name = "Alpha";
	A.next = NULL;
	B.name = "Bravo";
	B.next = &A;
	C.name = "Charlie";
	C.next = &B;


	printList(head);

	sort(&head);

	printList(head);
}

void sort(PERSON** head){
	
	if(strcmpi((*head)->next->name, (*head)->name) < 0){
		PERSON* _tmp = (*head);
		*head = (*head)->next;
		_tmp->next = (*head)->next;
		(*head)->next = _tmp;
	}

	printList((*head));
}

void printList(PERSON* head){
	while(head != NULL){
		printf("%s\n",head->name);
		head = head->next;
	}
	printf("\n");
}
```


----------

