#include #include #include #include #include #include #include #include #include using std::swap; int losowa_liczba(int min, int max) { static std::default_random_engine gen(std::random_device{}()); static std::uniform_int_distribution dist; return dist(gen, std::uniform_int_distribution::param_type{ min, max }); } void wypelnij(int* tablica, int rozmiar, int min = 0, int max = std::numeric_limits::max()) { for (int i = 0; i < rozmiar; ++i) tablica[i] = losowa_liczba(min, max); } bool jest_posortowane(int* tablica, int rozmiar) { return std::is_sorted(tablica, tablica + rozmiar); } double mierz_czas(int* tablica, int rozmiar, void(*funkcja_sortujaca)(int*, int)) { auto start = std::chrono::high_resolution_clock::now(); funkcja_sortujaca(tablica, rozmiar); auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration duration = end - start; return duration.count(); } /* parametry: - funkcja_sortujaca - wskanik na funkcjącą sortowanie, musi przyjmować dwa parametry: adres początku tablicy (int*) oraz jej rozmiar (int) - nazwa - nazwa testowanej funkcji, tylko w celach wypisania - output - strumien do ktorego beda zapisane wyniki, domyslnie std::cerr, przy ostatnim uruchomieniu warto nadpisac otwartym strumieniem plikowym, aby sobie zebrac wyniki do pliku - dodatkowe_miejsce - liczba dodatkowych elementow tablicy zaalokowanych PRZED poczatkiem tablicy, przykladowo gdy =1, pierwszym indeksem tablicy jest -1, ale dane rozpoczynaja sie od indeksu 0, moze sie przydac do sortowania przez wstawianie z wartownikiem */ void eksperyment(void(*funkcja_sortujaca)(int*, int), const std::string& nazwa, std::ostream& output = std::cerr, int dodatkowe_miejsce = 0) { //ustawienia const double limit_czasu = 25.0; //sekund const int powtorzen = 3; const int rozmiar_poczatkowy = 1 << 10; ///////////////////////////////////////// const int szerokosc = 100; int gwiazdek = szerokosc - nazwa.length() - 2; if (gwiazdek < 0) gwiazdek = 0; int i = 0; output << " "; for (; i < gwiazdek / 2; ++i) output << '*'; output << " " << nazwa << " "; for (; i < gwiazdek; ++i) output << '*'; output << "\n\n"; output.flush(); output << std::setw(9) << "N"; output << std::setw(1) << ""; for (int nr = 0; nr < powtorzen; ++nr) output << std::setw(9) << nr + 1 << " "; output << std::setw(12) << "średnia" << " "; output << "\n"; for (int rozmiar = rozmiar_poczatkowy; ; rozmiar *= 2) { output << std::setw(9) << rozmiar << ": "; output.flush(); int* pamiec = new int[dodatkowe_miejsce + rozmiar]; int* tablica = pamiec + dodatkowe_miejsce; double czas = 0.0; int* pattern = new int[rozmiar]; for (int nr = 0; nr < powtorzen; ++nr) { wypelnij(tablica, rozmiar); for (int i = 0; i < rozmiar; ++i) pattern[i] = tablica[i]; std::sort(pattern, pattern + rozmiar); double c = mierz_czas(tablica, rozmiar, funkcja_sortujaca); if (!jest_posortowane(tablica, rozmiar)) { output << "Tablica nieposortowana!!\n"; if (&output != &std::cerr) std::cerr << "Tablica nieposortowana!!\n"; return; } if (!std::equal(pattern, pattern + rozmiar, tablica, tablica + rozmiar)) { output << "Tablica zawiera inne wartosci niz powinna!!\n"; if (&output != &std::cerr) std::cerr << "Tablica zawiera inne wartosci niz powinna!!\n"; return; } czas += c; output.precision(6); output << std::fixed << c << " "; output.flush(); } czas /= powtorzen; output << std::setw(12) << std::fixed << czas << "\n"; output.flush(); delete[] pamiec; delete[] pattern; if (czas > limit_czasu) break; } output << "\n"; output.flush(); } void sortowanie_wybieranie(int* tablica, int rozmiar){ for (int i = 0; i < rozmiar - 1; i++) { int k = i; int x = tablica[i]; for (int ii = i+1; ii < rozmiar; ii++) { if (tablica[ii] < x) { k = ii; x = tablica[ii]; } } tablica[k]=tablica[i]; tablica[i]=x; } } void sortowanie_wstawianie(int* tablica, int rozmiar){ for (int i = 1; i < rozmiar; i++) { int x = tablica[i]; int ii = i - 1; while ((ii > -1) && (x < tablica[ii])) { tablica[ii+1] = tablica[ii]; ii=ii-1; } tablica[ii+1] = x; } } void sortowanie_babelkowe(int* tablica, int rozmiar) { for(int i = 0; i < rozmiar; i++) { for (int ii = 1; ii < rozmiar; ii++) { if (tablica[ii-1] > tablica[ii]) { swap(tablica[ii-1], tablica[ii]); } } } } void ulepszone_sortowanie_babelkowe(int* tablica, int rozmiar) { for(int i = 0; i < rozmiar; i++) { bool wejscie_do_ifa=false; for (int ii = 1; ii < rozmiar-i; ii++) { if (tablica[ii-1] > tablica[ii]) { swap(tablica[ii-1], tablica[ii]); wejscie_do_ifa = true; } } if (wejscie_do_ifa==false) {break;} } } void sortowanie_shella(int* tablica, int rozmiar) { int h = 1; while(h0){ for (int i=h; i= h) && ( x< tablica[j-h])){ tablica[j]=tablica[j-h]; j=j-h; } tablica[j]=x; } h=h/3; } } int main() { setlocale(LC_ALL, ""); std::ofstream wyniki("wyniki.txt"); //std::ostream& output = wyniki;//std::cerr; // Wypisanie do pliku (zamiast na ekran) std::ostream& output = std::cerr; // Wypisanie na ekran eksperyment(sortowanie_shella, "Sortowanie shella", output); // eksperyment(ulepszone_sortowanie_babelkowe, "Ulepszone sortowanie bąbelkowe", output); // eksperyment(sortowanie_babelkowe, "Sortowanie bąbelkowe", output); // eksperyment(sortowanie_wstawianie, "Sortowanie przez proste wstawianie", output); // eksperyment(sortowanie_wybieranie, "Sortowanie przez proste wybieranie", output); return 0; }