Binäre Suche schlägt fehl :( !!!!



  • Hallo!

    Ich bin neu hier und habe nur wenig Efahrung in der C-Programmierung 😃 . Ich sitze zur Zeit an einem Programm, mit dem ich eine doppelt verkettete Liste von Filmen anlege und in eine Datei speicher. Das sortierte Anlegen von Filmen, das Ansehen der sortierten Filme, das Löschen eines Filmes, das Löschen aller Filme, das Abspeichern der Liste in eine Datei und das Laden am Anfang des Programmes funtioniert bisher alles ganz gut. Ich habe noch nicht viel über Fehlerabfragungen in das Programm implementiert, aber ich dachte, dass das Wiederhiolen einer Eingabe, bei falscher Eingabe erstmal vernachlässigbar sei, solange ich die wichtigen Funktionen zustande bekomme.
    Ich sitze jetzt gerade an einer Suchfunktion. Ich dachte die "binäre Suche" wäre , auch wenn der Datensatz nicht riesig wird, die richtige Suchfunktion. Ich habe den Ansatz genommen, dass die Mitte der Liste berechnet wird, dann der gesuchte Wert mit dem der Mitte verglichen wird, wenn er nicht übereinstimmt wird nur noch verglichen ob er größer oder kleiner ist. Somit wird die linke und rechte Seite neu gesetzt, die Mitte neu berechnet und es geht so weiter bis der gesucht Wert gefunden wird oder links irgendwann größer gleich rechts wird.
    Ich habe mehrere Funktionen, die erste würde ich gerne nutzen, da ich sie, wenn sie richtig funktioniert, später am schnellsten sein könnte. Die zweite Funktion funktioniert schon, doch mein Zeiger "mid" fängt immer wieder von vorner der Liste an und geht dann bis zur Stelle wo "middle" berechnet wurde. Un das erste Listenelement findet die Suchfunktion nicht.

    Die Funktionen siehen folgender Maßen aus:

    "Binäre Suche" 1:
    test1(), die ich gerne nutzen würde, wird der Zeiger "mid" nur bei einer ungeraden Zahl an Listenelementen richtig berechnet, also ein Filmtitel angezeigt, und die Filme auch gefunden. Doch bei einer geraden zahl wird mir nicht mehr der Filmtitel angezeigt, sondern was zwischen den Beiden Filmen 2 und 3 ,wenn es 4 Filme sind, angezeigt. Das war bei mir dann das Filmstudio des Filmes.

    void test1(char *title, struct movie *start, struct movie *end){
    	struct movie *mid;
    
            if(!(strcmp(start->title, end->title) > 0)){
    		mid = (start + ((end -start) >> 1));
    		printf("Start->Title: %s, End->Title: %s\n", start->title, end->title);
    		printf("Mid->Title: %s\n", mid->title);
    		if(strcmp(title, mid->title) == 0) {
    			printf("Film \"%s\" gefunden\n", mid->title);
    		}
    		else if(strcmp(title, mid->title) < 0) {
    			end = mid->previous;
    			test(title, start, end);
    		}
    		else{
    			start = mid->next;
    			test(title, start, end);
    		}
    	}
    
    }
    

    "Binäre Suche" 2:
    Was mich nur an dieser Funktion test2() nervt, ist die Tatsache, dass der Zeiger "mid" immer wieder am Anfang startet und die ganze Liste durchläuft. Doch das ist die einzige Funktion bei der alle Filme, bis auf den ersten, gefunden werden. Ich habe auch schon probiert diese Funktion so zu ändern, dass mid dort startet wo der Zeiger stehengeblieben ist, doch dann wird durch left und right nicht die gesamte Liste durchsucht, da left zu früh kleiner right wird oder gleich 0.

    void test2(char *title, int left, int right) {
    	struct movie *mid;
    	int i, middle;
    
            if( left < right) {
    		mid = start;
    		middle = (left+right) / 2;
    		for(i = 0; i < middle; i++)
    			mid = mid->next;
    		printf("Mid->Title: %s\n", mid->title);
    		if(strcmp(title, mid->title) == 0) 
    			printf("Film \"%s\" gefunden\n", mid->title);
    		else if(strcmp(title, mid->title) < 0) {
    			right = middle-1;
    			test(title, left, right);
    		}
    		else {
    			left = middle+1;
    			test(title, left, right);
    		}
    	}
    	else
    		printf("Film wurde nicht gefunden!!\n\n");
    }
    

    Ich habe schon sehr viel rumprobiert, aber ich weiß nicht mehr weiter 😕 . Ich würde mich freuen, wenn mir jemand bei meinem Problem helfen könnte, denn ich möchte gerne diese Suchfunktion auch zum Einsetzen neuer Filme später nutzen, sofern das möglich ist.

    Hier ist nochmal das Programm zum runterladen
    http://uploaded.to/?id=6qaqxj



  • Hast du bei dir im Programm auch diese beiden Funktionen exakt so implementiert, denn beide rufen intern die Funktion test(...) auf, nicht test1(...) bzw. test2(...)?

    Aber m.E. macht eine binäre Suche bei einer verketteten Liste nicht viel Sinn
    (da du ja keine Indizes hast, mit denen du einfach zur Mitte springen kannst).

    Wenn du ein Array hast, dann könntest du auch einfach die Standard-Funktion bsearch(...) benutzen.


Anmelden zum Antworten