sortierung von listen
-
moin,
ich wollte eine einfach verkettete liste nach der größe sortieren.
die struktur schaut so aus:struct liste { liste *next; int zahl; }*liste_start, *liste_last;
;
next zeiger zeigt immer auf die daruafolgenden elemente, die zahl ist die zu sortieren. ich kann die liste erfolgreich erstellen und löschen, auch das tauschen kann ich.
nun zu meinem eigentlihcen problem. ich hab eine sortierfunktion "bubble".
void bubble() { liste *ptr1 = liste_start; liste *ptr2 = liste_start; liste *ptr3 = NULL; liste *ptr4 = NULL; for(; ptr1!=NULL; ptr1=ptr1->next) { for(ptr2=liste_start; ptr2!=NULL; ptr2=ptr2->next) { if(ptr1->next<ptr2->next) { ptr3 = ptr1; ptr4 = ptr2; tausche(ptr1,ptr2); /*ptr1 = ptr4; ptr2 = ptr3;*/ } } } }
;
auch mit ihr ist es möglich die liste elementweise zu sortiere (durch einfachen austausch ... bubblesort eben
man beachte dabei die innerste kontrollstruktur:if(ptr1->next<ptr2->next) { ptr3 = ptr1; ptr4 = ptr2; tausche(ptr1,ptr2); /*ptr1 = ptr4; ptr2 = ptr3;*/ }
damit ich beim austauschen nicht mit den zeigern durcheinander komme, muss ich sie bei jedem tausch, die postitionszeiger vertauschen ^^
dies würde ich gern innerhalb der der funktion "tausche" ermöglicht haben.
aber zuerst die funktion tausche:void tausche(liste*ptr1,liste*ptr2) { liste *swap = liste_start; liste *ptr3 = liste_start; liste *ptr4 = liste_start; ///////// TEST liste *ptr5 = NULL; liste *ptr6 = NULL; ptr5 = ptr1; ptr6 = ptr2; ////////// TEST ENDE if(liste_start==ptr1) { liste_start = ptr2; } else if(liste_start==ptr2) { liste_start = ptr1; } if(liste_last==ptr2) { liste_last = ptr1; } else if( liste_last==ptr1) { liste_last = ptr2; } // vorgänger for(;ptr3!=NULL && ptr3->next!=ptr1; ptr3=ptr3->next); for(;ptr4!=NULL && ptr4->next!=ptr2; ptr4=ptr4->next); if(ptr3!=NULL) { ptr3->next = ptr2; } if(ptr4!=NULL) { ptr4->next = ptr1; } swap = ptr1->next; ptr1->next = ptr2->next; ptr2->next = swap; /////////////// TEST ptr1 = ptr5; ptr2 = ptr6; ptr1=NULL; //////////////// TEST ENDE }
ich wollte dabei die tausch der positionen innerhalb der "tausch" funktion haben. die hab ich durch TEST und TEST ENDE angedeutet.
das problem ist, wenn die funktion beendet wird, sind die zeiger ptr1 und ptr2 nicht getauscht !!!
ich hatte erwartet, das die call by reference, die ich anwende (void tausche(liste*ptr1,liste*ptr2)), die adressen innerhlab der funktion mit nach ausen trägt.
mein dbugger agtmir, das ptr1 und ptr2 in kurz vorm aufruf der atuscheunktion die andressen besitzen: 0x00301dc0, 0x00301e00 und nachdem sie die funktion verlassen hat, bestitzten die zeiger wieder dieselben adressen.
ehrlich geasgt verwirrt mich das ein bisschen, da ich fest davona usgehe, das die zeiger genau gedreht sein sollten, da es sich bei den funktionsfrumpf um eine "call by reference" handelt.den einen oder anderen wird auffallen,d as ich am ende der funktion tausche noch "ptr1 = null" beigefügt habe, ich wollte damit bezwecken, dass auch der wert von ptr1 auserhalb der funktion NULL wird.
was ist die ursache dafür, ich bild mir ein, das unter linux genauso zu machen und hatte nie probleme gehabt ... ich benutze MSVC++ 6.0, vielleicht ein bug oder hab ich was dummes übersehene ?so aber nun der gesamte quellcode
#include <time.h> #include <stdio.h> #include <stdlib.h> #include <malloc.h> struct liste { liste *next; int zahl; }*liste_start, *liste_last; void add_entry(int i) { liste *ptr = NULL; if(liste_start==NULL) { liste_start = (liste*)malloc(sizeof(liste)); liste_start->next = NULL; liste_last = liste_start; ptr = liste_last; }else{ liste_last->next = (liste*)malloc(sizeof(liste)); liste_last = liste_last->next; liste_last->next = NULL; ptr = liste_last; } ptr->zahl = i; } void clear_liste() { liste *ptr = liste_start; liste *schlupf = ptr; while(ptr!=NULL) { schlupf = ptr; ptr = ptr->next; if(schlupf!=NULL) { free(schlupf); } } } void print_liste() { liste *ptr = liste_start; int i; for(i=0; ptr!=NULL; i++) { printf("%d\t\t%d\n",i,ptr->zahl); ptr = ptr->next; } } void tausche(liste*ptr1,liste*ptr2) { liste *swap = liste_start; liste *ptr3 = liste_start; liste *ptr4 = liste_start; ///////// TEST liste *ptr5 = NULL; liste *ptr6 = NULL; ptr5 = ptr1; ptr6 = ptr2; ////////// TEST ENDE if(liste_start==ptr1) { liste_start = ptr2; } else if(liste_start==ptr2) { liste_start = ptr1; } if(liste_last==ptr2) { liste_last = ptr1; } else if( liste_last==ptr1) { liste_last = ptr2; } // vorgänger for(;ptr3!=NULL && ptr3->next!=ptr1; ptr3=ptr3->next); for(;ptr4!=NULL && ptr4->next!=ptr2; ptr4=ptr4->next); if(ptr3!=NULL) { ptr3->next = ptr2; } if(ptr4!=NULL) { ptr4->next = ptr1; } swap = ptr1->next; ptr1->next = ptr2->next; ptr2->next = swap; /////////////// TEST ptr1 = ptr5; ptr2 = ptr6; ptr1=NULL; //////////////// TEST ENDE } void bubble() { liste *ptr1 = liste_start; liste *ptr2 = liste_start; liste *ptr3 = NULL; liste *ptr4 = NULL; for(; ptr1!=NULL; ptr1=ptr1->next) { for(ptr2=liste_start; ptr2!=NULL; ptr2=ptr2->next) { if(ptr1->next<ptr2->next) { ptr3 = ptr1; ptr4 = ptr2; tausche(ptr1,ptr2); ptr1 = ptr4; ptr2 = ptr3; } } } } int main() { int i; liste *ptr = liste_start; srand(time(NULL)); liste_start = NULL; liste_last = NULL; for(i=0; i<10; i++) add_entry(i); ptr = liste_start; print_liste(); printf("\n"); bubble(); print_liste(); clear_liste(); return 0; }
so ... haltet euch nicht zurück, stürzt euch drauf wie die geier
-
Ich hoffe mal, ich verstehe dein Problem jetzt richtig:
Da du die Zeiger selber ändern willst, mußt du sie "per Referenz" (eigentlich "per Zeiger") übergeben:void tausche(liste**p1,liste**p2) { ... }
-
ich danke dir sehr cstoll.
somit ist mein problem gelöstdie funktion sieht also dann so aus
void tausche(liste**ptr1,liste**ptr2) { liste *swap = liste_start; liste *ptr3 = liste_start; liste *ptr4 = liste_start; ///////// TEST liste *ptr5 = NULL; liste *ptr6 = NULL; ptr5 = *ptr1; ptr6 = *ptr2; ////////// TEST ENDE if(liste_start==*ptr1) { liste_start = *ptr2; } else if(liste_start==*ptr2) { liste_start = *ptr1; } if(liste_last==*ptr2) { liste_last = *ptr1; } else if( liste_last==*ptr1) { liste_last = *ptr2; } // vorgänger for(;ptr3!=NULL && ptr3->next!=*ptr1; ptr3=ptr3->next); for(;ptr4!=NULL && ptr4->next!=*ptr2; ptr4=ptr4->next); if(ptr3!=NULL) { ptr3->next = *ptr2; } if(ptr4!=NULL) { ptr4->next = *ptr1; } swap = (*ptr1)->next; (*ptr1)->next = (*ptr2)->next; (*ptr2)->next = swap; /////////////// TEST *ptr1 = ptr6; *ptr2 = ptr5; //ptr1=NULL; //////////////// TEST ENDE } void bubble() { liste *ptr1 = liste_start; liste *ptr2 = liste_start; liste *ptr3 = NULL; liste *ptr4 = NULL; for(; ptr1!=NULL; ptr1=ptr1->next) { for(ptr2=liste_start; ptr2!=NULL; ptr2=ptr2->next) { if(ptr1->next<ptr2->next) { ptr3 = ptr1; ptr4 = ptr2; tausche(&ptr1,&ptr2); /* ptr1 = ptr4; ptr2 = ptr3;*/ } } } }
also nochmals danke für die schnelle hilfe