Błędne sortowanie listy stringów.

0

Witam,
staram się posortować alfabetycznie listę stringów poprzez wybór, lecz wraz z zwiększaniem ilosci danych są coraz większe błędy (więcej niż 3 rekordy - pojawiaja sie bledy).
Proszę o jakąś podpowiedź co tu "nie gra"...

void sortowanie(list_t* slista)
{
 
    dane_t *sorter, *tmp, *buff;
    sorter=slista->first;
    dane_t buff2;

    while(sorter)
    {

        buff=sorter;
        for(tmp=sorter; tmp!=NULL; tmp=tmp->next)
        {

            if(strcoll(sorter->nazwisko, tmp->nazwisko)>=0)
            {
                buff=tmp;
            }

        }


        buff2.nazwisko=buff->nazwisko;
        buff->nazwisko=sorter->nazwisko;
        sorter->nazwisko=buff2.nazwisko;

        printf("# %s %s\n", sorter->nazwisko, buff->nazwisko);

        sorter=sorter->next;

    }

}
0
  1. Wstaw kod między <code><code class="c"></code></code>
  2. Nie wiem co to jest nazwisko, ale stawiam że jakaś tablica znaków. W tym przypadku nie możesz użyć =, tylko musisz czegoś w stylu strcpy.
  3. Po co cała struktura buff2, żeby zamieniać miejscami stringi? Potrzebujesz jedynie tablicy znaków.
for(tmp=sorter; tmp!=NULL; tmp=tmp->next)
{
    if(strcoll(sorter->nazwisko, tmp->nazwisko)>=0)
    {
        buff=tmp;
    }

}

Ta pętla znajdujesz ostatnie nazwisko mniejsze niż sorter->nazwisko. Żeby znaleźć pierwsze, musisz przerwać pętlę gdy już znaleziono cokolwiek:

buff = tmp;
break;
0

pętla for, ma za zadanie znaleźć najmniejszy element (najbliższy początku alfabetu) więc nie może się zatrzymać po znalezieniu pierwszego elementu.
edit. chyba że pierwszy jest najmniejszy -> to chyba tu jest błąd

Co dziwne gdy wielokrotnie użyję tej funkcji na danych, to po którymś razie są posortowane, więc pewnie po prostu w którymś momencie pomija jakiś element .

Zmiana sposobu przypisania nie zmieniła efektu... nadal lista jest częściowo posortowana, a częściowo nie.

0
Jagdire napisał(a):

pętla for, ma za zadanie znaleźć najmniejszy element (najbliższy początku alfabetu) więc nie może się zatrzymać po znalezieniu pierwszego elementu.
Tylko że tego nie robi. Znajduje ostatni element mniejszy niż sorter.

0
void sortowanie(list_t* slista)
{   
    dane_t *sorter, *tmp, *buff;
    sorter=slista->first;
    dane_t buff2;

    while(sorter)
    {
        buff=sorter;

        for(tmp=sorter; tmp!=NULL; tmp=tmp->next)
        {

            if((strcoll(buff->nazwisko, tmp->nazwisko)>=0))          // wystarczyło zmnienić porównywanie z sortera, na buff
                buff=tmp;
            
        }

        buff2.nazwisko=strdup(buff->nazwisko);
        buff->nazwisko=sorter->nazwisko;
        sorter->nazwisko=buff2.nazwisko;

        printf("# %s %s\n", sorter->nazwisko, buff->nazwisko);

        sorter=sorter->next;
    }
}

Ok już wszystko śmiga :)
Tak jak napisałem w komentarzu, okazało się ze zamiast porównywać po "buff", to było porównywane po "sorter".

0

Obecnie z twego kodu pamięć cieknie na potęgę.
Skoro masz listę to powinieneś przestawiać elementy listy poprzez zmianę ich łączenia a nie kopiowanie (tak jest znacznie szybciej).
By móc to zrobić musisz poprawić prototyp funkcji sortowania:

void sortowanie(list_t** slista)

1 użytkowników online, w tym zalogowanych: 0, gości: 1