• 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ł?

Object Storage Arubacloud
0 głosów
290 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 Ekspert (344,860 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ź 173 wizyt
0 głosów
4 odpowiedzi 312 wizyt
+3 głosów
2 odpowiedzi 9,586 wizyt

92,555 zapytań

141,404 odpowiedzi

319,557 komentarzy

61,940 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...