Dlaczego te algorytmy są lepsze? Oto wykres zależności czasu trwania obliczeń od ilości elementów:
Wykres zależności czasu trwania obliczeń od ilości elementów z pominięciem sortowania bąbelkowego:
Sortowanie szybkie:
//------------------------------------------------------------------------------
//------------SORTOWANIE SZYBKIE -----------------------------------------------
//------------------------------------------------------------------------------
/**
Wywoływana rekurencyjnie funkcja szybkiego sortowania
tab - sortowana tablica
index_pierwszego elementu :)
index_ostatniego elementu :)
*/
void quick_alg(int index_pierwszego, int index_ostatniego, int* tab){
int i, i2, tmp, srodek;
i = (index_pierwszego + index_ostatniego) / 2;
srodek = tab[i];
tab[i] = tab[index_ostatniego];
for( i2 = index_pierwszego, i = index_pierwszego ; i < index_ostatniego; i++){
if( tab[i] < srodek){
tmp = tab[i];
tab[i] = tab[i2];
tab[i2] = tmp;
i2++;
}
}
tab[index_ostatniego] = tab[i2];
tab[i2] = srodek;
if( (i2 + 1) < index_ostatniego){
quick_alg(i2 + 1, index_ostatniego, tab); //rekurencyjne wykonanie quicksorta dla prawej partycji
}
if( index_pierwszego < (i2 - 1)){
quick_alg(index_pierwszego, (i2 - 1), tab); //rekurencyjne wykonanie quicksorta dla lewej partycji
}
}
/**
Funkcja zwraca wartość double, jest to czas wykonania operacji
Argument n jest ilością elementów w tablicy
Argument przyp jest przypadkiem ulozenia elementow 0-posortowane 1-losowo 2-posortowane wspak
*/
double quick(int n, short int przyp){
int *tab; // tablica na której będzie wykonywany algorytm
clock_t time_przed; // pomiar czasu prz sortowaniem
clock_t time_po; // pomiar czasu po sortowaniu
double time_roznica; // różnica czasu przed i po sortowaniu zwracana przez funkcję difftime
tab = new int [n];
wypelnij(tab, przyp, n, 0); // wypełnianie tablicy
wypisz(tab, n); // ewentualne wyswietlanie elementow tablicy dla sprawdzenia poprawnosci sortowania
time_przed = pobierz_czas(); // pomiar czasu przed sortowaniem
quick_alg(0,n-1, tab); // quicksort
time_po = pobierz_czas(); // pomiar czasu po sortowaniu
wypisz(tab, n); // ewentualne wyswietlanie elementow tablicy dla sprawdzenia poprawnosci sortowania
delete [] tab;
time_roznica = difft(time_po, time_przed);
cout << time_roznica;
return time_roznica;
}
Sortowanie przez scalanie:
//------------------------------------------------------------------------------
//------------SORTOWANIE PRZEZ SCALANIE ----------------------------------------
//------------------------------------------------------------------------------
/**
Wywoływana rekurencyjnie funkcja sortowania przez scalanie
tab - sortowana tablica
pom - tablica pomocnicza
index_pierwszego elementu :)
index_ostatniego elementu :)
*/
void scalanie_alg(int index_pierwszego, int index_ostatniego, int* tab, int* pom){
int podzial;
int j,k,i;
podzial = (1 + index_pierwszego + index_ostatniego) / 2; // przygotowanie podzialu zbioru na 2 czesci
if( index_ostatniego - podzial > 0){ // sortowanie rekurencyjne podzbioru drugiego
scalanie_alg(podzial, index_ostatniego, tab, pom);
}
if( podzial - index_pierwszego > 1){ // sortowanie rekurencyjne podzbioru pierwszego
scalanie_alg(index_pierwszego, podzial - 1, tab, pom);
}
j = index_pierwszego;
k = podzial;
for( i = index_pierwszego; i <= index_ostatniego; i++){ // scalanie
if(((index_ostatniego >= k) && (tab[k] < tab[j])) || ( j == podzial)){ // jezeli index pierwszego elementu z pierwszego zbioru jest rowny podzial tzn ze jestesmy
pom[i] = tab[k]; // na najnizszym poziomie rekurencji
k++;
}else{
pom[i] = tab[j];
j++;
}
}
for( i = index_pierwszego; i <= index_ostatniego; i++){ // przepisywanie z tablicy pomocniczej do tab juz po scaleniu
tab[i] = pom[i];
}
}
/**
Funkcja zwraca wartość double, jest to czas wykonania operacji
Argument n jest ilością elementów w tablicy
Argument przyp jest przypadkiem ulozenia elementow 0-posortowane 1-losowo 2-posortowane wspak
*/
double scalanie(int n, short int przyp){
int *tab; // tablica na której będzie wykonywany algorytm
clock_t time_przed; // pomiar czasu prz sortowaniem
clock_t time_po; // pomiar czasu po sortowaniu
double time_roznica; // różnica czasu przed i po sortowaniu zwracana przez funkcję difftime
int *pom; // tablica pomocnicza
tab = new int [n];
pom = new int [n];
wypelnij(tab, przyp, n, 0); // wypełnianie tablicy
wypisz(tab, n); // ewentualne wyswietlanie elementow tablicy dla sprawdzenia poprawnosci sortowania
time_przed = pobierz_czas(); // pomiar czasu przed sortowaniem
scalanie_alg(0,n-1, tab, pom);
time_po = pobierz_czas(); // pomiar czasu po sortowaniu
wypisz(tab, n); // ewentualne wyswietlanie elementow tablicy dla sprawdzenia poprawnosci sortowania
delete [] tab;
time_roznica = difft(time_po, time_przed);
cout << time_roznica;
return time_roznica;
}
Sortowanie przez kopcowanie:
//------------------------------------------------------------------------------
//------------SORTOWANIE PRZEZ KOPCOWANIE --------------------------------------
//------------------------------------------------------------------------------
/**
Funkcja zwraca wartość double, jest to czas wykonania operacji
Argument n jest ilością elementów w tablicy
Argument przyp jest przypadkiem ulozenia elementow 0-posortowane 1-losowo 2-posortowane wspak
*/
double kopcowanie(int n, short int przyp){
int *tab; // tablica na której będzie wykonywany algorytm
clock_t time_przed; // pomiar czasu prz sortowaniem
clock_t time_po; // pomiar czasu po sortowaniu
double time_roznica; // różnica czasu przed i po sortowaniu zwracana przez funkcję difftime
int a,b,tmp2,tmp;
tab = new int [n];
wypelnij(tab, przyp, n, 0); // wypełnianie tablicy
wypisz(tab, n); // ewentualne wyswietlanie elementow tablicy dla sprawdzenia poprawnosci sortowania
time_przed = pobierz_czas(); // pomiar czasu przed sortowaniem
// Kopcowanie
for( int i=2; i<=(n-1);i++){
a=i;
tmp=tab[i];
b=a/2;
while( (tmp>tab[b]) && (b>0)){
tab[a]=tab[b];
a=b;
b=a/2;
}
tab[a]=tmp;
}
wypisz(tab, n); // ewentualne wyswietlanie elementow tablicy dla sprawdzenia poprawnosci sortowania
//Odkopcowanie
for( int i = (n-1); i>1; i--){
tmp2 = tab[1];
tab[1] = tab[i];
tab[i] = tmp2;
a=1;
b=2;
while( b<i){
if( (b+1<i) &&(tab[b]<tab[b+1]) ){
tmp = 1 + b;
}
else{
tmp = b;
}
if( !( tab[tmp] > tab[a] ) ){
break;
}
tmp2 = tab[a];
tab[a] = tab[tmp];
tab[tmp] = tmp2;
a=tmp;
b=2*a;
}
}
time_po = pobierz_czas(); // pomiar czasu po sortowaniu
wypisz(tab, n); // ewentualne wyswietlanie elementow tablicy dla sprawdzenia poprawnosci sortowania
delete [] tab;
time_roznica = difft(time_po, time_przed);
cout << time_roznica;
return time_roznica;
}
Sortowanie Shell'a:
//------------------------------------------------------------------------------
//------------SORTOWANIE SHELL -------------------------------------------------
//------------------------------------------------------------------------------
/**
Funkcja zwraca wartość double, jest to czas wykonania operacji
Argument n jest ilością elementów w tablicy
Argument przyp jest przypadkiem ulozenia elementow 0-posortowane 1-losowo 2-posortowane wspak
*/
double shell(int n, short int przyp, int param){
int *tab; // tablica na której będzie wykonywany algorytm
clock_t time_przed; // pomiar czasu prz sortowaniem
clock_t time_po; // pomiar czasu po sortowaniu
double time_roznica; // różnica czasu przed i po sortowaniu zwracana przez funkcję difftime
int h,i,licz,a; // h -odległość
tab = new int [n];
wypelnij(tab, przyp, n, 0); // wypełnianie tablicy
wypisz(tab, n); // ewentualne wyswietlanie elementow tablicy dla sprawdzenia poprawnosci sortowania
time_przed = pobierz_czas(); // pomiar czasu przed sortowaniem
h = 1; //ustawianie parametru h
while( h < n){
h=1 + param*h;
}
h = h/9;
if(!h) h++; // istotne jedynie dla bardzo małych tablic
while( h){
for( licz = n - 1 - h; !(licz < 0); licz--){
i = licz + h;
a = tab[licz];
for( ;(n > i) && (tab[i] < a);){ //sortowanie przez wstawianie
tab[i - h] = tab[i];
i += h;
}
tab[i - h] = a;
}
h = h/3;
}
time_po = pobierz_czas(); // pomiar czasu po sortowaniu
wypisz(tab, n); // ewentualne wyswietlanie elementow tablicy dla sprawdzenia poprawnosci sortowania
delete [] tab;
time_roznica = difft(time_po, time_przed);
cout << time_roznica;
return time_roznica;
}
Funkcje pomocnicze:
/*
Pobiera czas metoda zalezna od globalnej flagi
*/
time_t pobierz_czas(){
if( fczas==1){
return clock ();
}
else{
return time(NULL);
}
}
/*
Oblicza czas wykonywania sie algorytmu dla metod clock() i time()
*/
double difft(time_t time_po, time_t time_przed){
if( fczas==1){
return (difftime(time_po, time_przed) / CLOCKS_PER_SEC);
}
else{
return difftime(time_po, time_przed);
}
}
//---------------------------------------
//------------WYPELNIANIE TABLICY--------
//---------------------------------------
void wypelnij(int* tab,short int przyp, int n, int zakres){
switch(przyp){
// posortowane
case 0:
for( int i=0; i<n;i++){
if(zakres!=0){
tab[i]= i%zakres;
}
else{
tab[i]= i;
}
}
break;
// losowo
case 1:
for( int i=0; i<n;i++){
if(zakres!=0){
tab[i]= rand()%zakres;
}
else{
tab[i]= rand();
}
}
break;
// wspak
case 2:
for( int i=0; i<n;i++){
if(zakres!=0){
tab[i]= (n-i)%zakres;
}
else{
tab[i]= (n-i);
}
}
break;
}
}
//----------------------------------------------------
//------------WYPISYWANIE POSORTOWANEJ TABLICY--------
//----------------------------------------------------
/**
Funkcja wypisujaca elementy posortowanej tablicy, spam do testowania poprawnosci sortowania
n -liczba elementow
tab - nasza tablica
*/
void wypisz(int* tab, int n){
if( wyswietl==1){
cout << endl << endl <<endl;
for( int i=0;i<n;i++){
cout<<tab[i];
if( (i%8)==0){
cout << "\n";
}
else{
cout << "\t";
}
}
cout << "czas: ";
}
}


Dodatki SourceMod




Moja zawartość
Mężczyzna

