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öst 😉 😉 😉

    die 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 😉


Anmelden zum Antworten