• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Algorytm sortujący. Czy ma potencjał?

0 głosów
611 wizyt
pytanie zadane 20 sierpnia 2020 w C i C++ przez Wovri Nowicjusz (120 p.)

Dzień dobry! Ostatnio obudziłem się z pewnym pomysłem na algorytm sortujący. Ciekaw jestem czy ktoś z was spotkał się z czymś podobnym i czy w ogóle może mieć to jakieś zastosowanie.

Z moich testów wynikło, że przy większej ilości liczb do posortowania, działa szybciej niż quick sort. Aktualnie program ma zakres od 1 do "dowolnej liczby" (w odpowiednim zakresie dla zmiennej oczywiście). Myślę, że można by również dodać liczby ujemne, ale nie o to chodzi. Niestety nie da się sortować liczb zmienno-przecinkowych.

Zasada programu jest banalnie prosta:

  • Program pobiera dane wejściowe i losuje liczby do posortowania,
  1. Algorytm tworzy drugą tabelkę i wpisuje do danej komórki ilość występowania konkretnej liczby,
  2. później wypisuje w kolejności do tabelki pierwotnej liczby.

Kod algorytmu:

(*tab- tabela zawierająca nieposortowane dane, n- liczba liczb z- maksymalny zakres)

void sortowanie (int *tab, int n, int z)
{
    //inicjowanie tablicy do zapisu ilosci liczb
    int *wew_tab;
    wew_tab = new int [z+1] {0};

    //wpisanie wartosci do tablicy
    for (int i=0; i<n; i++)
    {
        wew_tab[tab[i]]+=1;
    }

    //zapis posortowanych danych do tablicy glownej
    int j=0;
    for (int i=0; i<z;i++)
    {
        if (wew_tab[i]>0)
        {
            tab[j]=i;
            wew_tab[i]-=1;
            j++;
            i--;
            z++;
        }
        //koniec dzialania algorytmu po osiagnieciu max
        if (j==n)
        {
            break;
        }

    }
    delete [] wew_tab;
}

Przykładowy wynik:

 

Kod programu porównującego algorytm do quick sorta:

#include <iostream>
#include <time.h>
#include <windows.h>

using namespace std;

int ile, zakres;
clock_t start,stop;
double czas;

void sortowanie (int *tab, int n, int z);

void quicksort(int *tablica, int lewy, int prawy);

int main()
{
    cout<<"Ile losowych liczb w tablicy: ";
    cin>>ile;
    cout<<"Jaki ma byc maksymalny zakres losowania liczb. 1-";
    cin>>zakres;

    //dynamiczne alokowanie pamieci
    int *tablica;
    tablica=new int [ile];
    int *tablica_q;
    tablica_q=new int [ile];

    //inicjowanie generatora
    srand(time(NULL));

    //wczytywanie losowych liczb do tablicy

    for(int i=0; i<ile; i++)
    {
        tablica[i] = rand()%zakres+1;
        tablica_q[i] = tablica[i];  //przepisywanie tablicy do tablicy q
    }


/*    cout<<"\nPrzed posortowaniem: "<<endl;
    for(int i=0; i<ile; i++)
    {
        cout<<tablica[i]<<" ";
    }
*/
    cout<<"\n\nSortuje teraz 'tab sort'. Prosze czekac!";
    start = clock();
    sortowanie(tablica,ile,zakres);
    stop = clock();
    czas = (double)(stop-start) / CLOCKS_PER_SEC;
    cout<<endl<<"Czas sortowania 'tab sort': "<<czas<<" s"<<endl;


    cout<<endl<<"Sortuje teraz algorytmem quicksort. Prosze czekac!";
    start = clock();
    quicksort(tablica_q, 0, ile-1);
    stop = clock();
    czas = (double)(stop-start) / CLOCKS_PER_SEC;
    cout<<endl<<"Czas sortowania quicksort: "<<czas<<" s"<<endl;

/*    cout<<"\nPo posortowaniu tab sort: "<<endl;
    for(int i=0; i<ile; i++)
    {
        cout<<tablica[i]<<" ";
    }


    cout<<"\nPo posortowaniu quick sort: "<<endl;
    for(int i=0; i<ile; i++)
    {
        cout<<tablica_q[i]<<" ";
    }
*/

    cout<<endl;
    delete [] tablica;
    delete [] tablica_q;

    return 0;
}
void sortowanie (int *tab, int n, int z)
{
    //inicjowanie tablicy do zapisu ilosci liczb
    int *wew_tab;
    wew_tab = new int [z+1] {0};

    //wpisanie wartosci do tablicy
    for (int i=0; i<n; i++)
    {
        wew_tab[tab[i]]+=1;
    }

    //zapis posortowanych danych do tablicy glownej
    int j=0;
    for (int i=0; i<z;i++)
    {
        if (wew_tab[i]>0)
        {
            tab[j]=i;
            wew_tab[i]-=1;
            j++;
            i--;
            z++;
        }
        //koniec dzialania algorytmu po osiagnieciu max
        if (j==n)
        {
            break;
        }

    }
    delete [] wew_tab;
}

void quicksort(int *tablica, int lewy, int prawy)
{
    int v=tablica[(lewy+prawy)/2];
    int i,j,x;
    i=lewy;
    j=prawy;
    do
    {
        while(tablica[i]<v) i++;
        while(tablica[j]>v) j--;
        if(i<=j)
        {
            x=tablica[i];
            tablica[i]=tablica[j];
            tablica[j]=x;
            i++;
            j--;
        }
    }
    while(i<=j);
    if(j>lewy) quicksort(tablica,lewy, j);
    if(i<prawy) quicksort(tablica, i, prawy);
}

 

1 odpowiedź

+1 głos
odpowiedź 20 sierpnia 2020 przez adrian17 Mentor (355,240 p.)
  1. Algorytm tworzy drugą tabelkę i wpisuje do danej komórki ilość występowania konkretnej liczby,
  2. później wypisuje w kolejności do tabelki pierwotnej liczby.

Brzmi jak podręcznikowy counting sort (choć trochę dziwnie wygląda część z `z++`).

https://en.wikipedia.org/wiki/Counting_sort

Rzuć okiem na porównanie z quicksortem tutaj:

https://stackoverflow.com/a/47736898/2468469

 

komentarz 20 sierpnia 2020 przez Wovri Nowicjusz (120 p.)

No faktycznie to counting sort. Dzięki za informację! smiley

Podobne pytania

0 głosów
1 odpowiedź 732 wizyt
pytanie zadane 12 grudnia 2024 w Algorytmy przez MARECKIdev Nowicjusz (120 p.)
0 głosów
1 odpowiedź 498 wizyt
0 głosów
4 odpowiedzi 633 wizyt

93,774 zapytań

142,731 odpowiedzi

323,383 komentarzy

63,378 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Twierdza Linux. Bezpieczeństwo dla dociekliwych

Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.

...