Advertisement
baadgeorge

s3

Dec 22nd, 2020
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.62 KB | None | 0 0
  1. #include <chrono>
  2. #include <iostream>
  3. #include <Windows.h>
  4.  
  5. // ОПРЕДЕЛЕНИЕ СТРУКТУРЫ ДАННЫХ ДЛЯ СОРТИРОВКИ
  6. struct DATA {
  7.     __int64* mas; // МАССИВ ДАННЫХ
  8.     __int64 size; // РАЗМЕР
  9.     __int64 min;  // МИНИМАЛЬНОЕ ЗНАЧЕНИЕ
  10.     __int64 max;  // МАКСИМАЛЬНОЕ ЗНАЧЕНИЕ
  11. };
  12.  
  13. // ТИП СОРТИРОВКИ (ДЛЯ ПЕРЕДАЧИ В ФУНКЦИЮ)
  14. enum type
  15. {
  16.     typeShakeSort, typeShellSort
  17. };
  18.  
  19. typedef struct DATA DATA;
  20.  
  21. // ФУНКЦИЯ ОТОБРАЖЕНИЯ КУРСОРА В КОНСОЛИ
  22. void ShowConsoleCursor(bool showFlag)
  23. {
  24.     HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
  25.  
  26.     CONSOLE_CURSOR_INFO cursorInfo;
  27.  
  28.     GetConsoleCursorInfo(out, &cursorInfo);
  29.     cursorInfo.dwSize = 1;
  30.     cursorInfo.bVisible = showFlag;
  31.     SetConsoleCursorInfo(out, &cursorInfo);
  32. }
  33.  
  34. // ФУНКЦИЯ НАХОЖДЕНИЯ СЛУЧАЙНОГО ЧИСЛА
  35. int random(__int64 N)
  36. {
  37.     int result = rand() % N;
  38.     return result;
  39. }
  40.  
  41. // ФУНКЦИЯ ФОРМИРОВАНИЯ СЛУЧАЙНОГО МАССИВА ДАННЫХ
  42. int formRandArray(DATA* data)
  43. {
  44.     if (data->min > data->max) return -1;
  45.     for (__int64 i = 0; i < data->size; i++)
  46.     {
  47.         data->mas[i] = data->min + random(data->max - data->min);
  48.     }
  49.     return 0;
  50. }
  51.  
  52. // ФУНКЦИЯ ПЕРЕСТАНОВКИ ЭЛЕМЕНТОВ ДАННЫХ МЕСТАМИ
  53. template <class T>
  54. void Swap(T& a, T& b)
  55. {
  56.     T tmp = NULL;
  57.     tmp = a;
  58.     a = b;
  59.     b = tmp;
  60.     return;
  61. }
  62.  
  63. // ФУНКЦИЯ ВЫВОДА МАССИВА НА ЭКРАН
  64. void printMas(DATA& data)
  65. {
  66.     for (int i = 0; i < data.size; i++)
  67.         std::cout << data.mas[i] << ' ';
  68.     std::cout << '\n';
  69. }
  70.  
  71. std::pair<int, int> ShakeSort(DATA& data) // КОКТЕЙЛЬНАЯ СОРТИРОВКА
  72. {
  73.     std::pair<int, int> countPair; // ВОЗВРАЩАЕМЫЙ АРГУМЕНТ ТИПА "ПАРА"
  74.  
  75.     int countComp = 0; // ЧИСЛО СРАВНЕНИЙ
  76.     int countSwap = 0; // ЧИСЛО ПЕРЕАДРЕСАЦИЙ
  77.     int i = 0;         // ИНДЕКСНАЯ ПЕРЕМЕННАЯ
  78.     int n = data.size - 1; // РАЗМЕР ДАННЫХ
  79.  
  80.     bool isSorted = false; // ФЛАГ "МАССИВ ОТСОРТИРОВАН"
  81.  
  82.     // ПОКА МАССИВ НЕ ОТСОРТИРОВАН
  83.     while (!isSorted)
  84.     {
  85.         // МАССИВ ОТСОРТИРОВАН
  86.         isSorted = true;
  87.         // ЦИКЛ ПО МАССИВУ  ОТ ПЕРВОГО ДО ПОСЛЕДНЕГО ЭЛЕМЕНТА
  88.         for (int j = i; j < n; j++)
  89.         {
  90.             // ЕСЛИ ТЕКУЩИЙ ЭЛЕМЕНТ БОЛЬШЕ СЛЕДУЮЩЕГО
  91.             if (data.mas[j] > data.mas[j + 1])
  92.             {
  93.                 // ПЕРЕМЕНА ЭЛЕМЕНТОВ МЕСТАМИ
  94.                 Swap(data.mas[j], data.mas[j + 1]);
  95.                 // УВЕЛИЧЕНИЕ ЧИСЛА ПЕРЕСТАНОВОК
  96.                 countSwap++;
  97.                 // МАССИВ НЕ ОТСОРТИРОВАН
  98.                 isSorted = false;
  99.             }
  100.             // УВЕЛИЧЕНИЕ ЧИСЛА СРАВНЕНИЙ
  101.             countComp++;
  102.         }
  103.         // ЕСЛИ МАССИВ ОТСОРТИРОВАН
  104.         if (isSorted)
  105.             break; // ВЫХОДИМ ИЗ ФУНКЦИИ
  106.         // УМЕНЬШАЕМ ПРАВУЮ ГРАНИЦУ НА 1
  107.         n--;
  108.  
  109.         // МАССИВ ОТСОРТИРОВАН
  110.         isSorted = true;
  111.         // ЦИКЛ ОТ ПОСЛЕДНЕГО ЭЛЕМЕНТА ДО ПЕРВОГО
  112.         for (int k = n - 1; k >= i; k--)
  113.         {
  114.             // ЕСЛИ ТЕКУЩИЙ ЭЛЕМЕНТ БОЛЬШЕ ПРЕДЫДУЩЕГО
  115.             if (data.mas[k] > data.mas[k + 1])
  116.             {
  117.                 // ПЕРЕМЕНА ЭЛЕМЕНТОВ МАССИВА МЕСТАМИ
  118.                 Swap(data.mas[k], data.mas[k + 1]);
  119.                 // УВЕЛИЧЕНИЕ ЧИСЛА ПЕРЕСТАНОВОК
  120.                 countSwap++;
  121.                 // МАССИВ НЕ ОТСОРТИРОВАН
  122.                 isSorted = false;
  123.             }
  124.             // УВЕЛИЧЕНИЕ ЧИСЛА СРАВНЕНИЙ
  125.             countComp++;
  126.         }
  127.         // УВЕЛИЧИВАЕМ ЛЕВУЮ ГРАНИЦУ НА 1
  128.         i++;
  129.     }
  130.  
  131.     countPair.first = countSwap;  // ПЕРВОЕ ЗНАЧЕНИЕ "ПАРЫ" - ЧИСЛО ПЕРЕСТАНОВОК
  132.     countPair.second = countComp; // ВТОРОЕ ЗНАЧЕНИЕ "ПАРЫ" - ЧИСЛО СРАВНЕНИЙ
  133.     return countPair;             // ФУНКЦИЯ ВОЗВРАЩАЕТ НАЙДЕННУЮ "ПАРУ" ЧИСЕЛ
  134. }
  135.  
  136. std::pair<int, int> ShellSort(DATA& data) // СОРТИРОВКА ШЕЛЛА
  137. {
  138.     std::pair<int, int> countPair;
  139.  
  140.     int countComp = 0;
  141.     int countSwap = 0;
  142.     int h = 0;
  143.  
  144.     while (h < data.size / 3)
  145.     {
  146.         h = 3 * h + 1;
  147.     }
  148.  
  149.     for (h; h > 0; h = (h - 1) / 3)
  150.     {
  151.         for (int i = h; i < data.size; i++)
  152.         {
  153.             int j = i;
  154.             int tmp = data.mas[i];
  155.  
  156.             for (j = i; j >= h && data.mas[j - h] > tmp; j -= h)
  157.             {
  158.                 countComp++;
  159.                 countSwap++;
  160.                 data.mas[j] = data.mas[j - h];
  161.  
  162.             }
  163.             countComp++;
  164.             data.mas[j] = tmp;
  165.             countSwap++;
  166.         }
  167.     }
  168.  
  169.     countPair.first = countSwap;
  170.     countPair.second = countComp;
  171.     return countPair;
  172. }
  173.  
  174. std::pair<int, int> ShakeSortPrint(DATA& data) // КОКТЕЙЛЬНАЯ СОРТИРОВКА (С ВЫВОДОМ)
  175. {
  176.     std::pair<int, int> countPair;
  177.  
  178.     int countComp = 0;
  179.     int countSwap = 0;
  180.     int i = 0;
  181.     int n = data.size - 1;
  182.  
  183.     bool isSorted = false;
  184.  
  185.     while (!isSorted)
  186.     {
  187.         isSorted = true;
  188.         for (int j = i; j < n; j++)
  189.         {
  190.             if (data.mas[j] > data.mas[j + 1])
  191.             {
  192.                 Swap(data.mas[j], data.mas[j + 1]);
  193.                 countSwap++;
  194.                 printMas(data);
  195.                 isSorted = false;
  196.             }
  197.             countComp++;
  198.         }
  199.         if (isSorted)
  200.             break;
  201.         n--;
  202.  
  203.         isSorted = true;
  204.         for (int k = n - 1; k >= i; k--)
  205.         {
  206.             if (data.mas[k] > data.mas[k + 1])
  207.             {
  208.                 Swap(data.mas[k], data.mas[k + 1]);
  209.                 countSwap++;
  210.                 printMas(data);
  211.                 isSorted = false;
  212.             }
  213.             countComp++;
  214.         }
  215.         i++;
  216.     }
  217.  
  218.     countPair.first = countSwap;
  219.     countPair.second = countComp;
  220.     return countPair;
  221. }
  222.  
  223. std::pair<int, int> ShellSortPrint(DATA& data) // СОРТИРОВКА ШЕЛЛА (С ВЫВОДОМ)
  224. {
  225.     std::pair<int, int> countPair;
  226.  
  227.     int countComp = 0;
  228.     int countSwap = 0;
  229.     int h = 0;
  230.  
  231.     while (h < data.size / 3)
  232.     {
  233.         h = 3 * h + 1;
  234.     }
  235.  
  236.     std::cout << "h = " << h << ": ";
  237.     printMas(data);
  238.  
  239.     for (h; h > 0; h = (h - 1) / 3)
  240.     {
  241.         for (int i = h; i < data.size; i++)
  242.         {
  243.             int j = i;
  244.             int tmp = data.mas[i];
  245.  
  246.             for (j = i; j >= h && data.mas[j - h] > tmp; j -= h)
  247.             {
  248.                 countComp++;
  249.                 countSwap++;
  250.                 data.mas[j] = data.mas[j - h];
  251.                 std::cout << "h = " << h << ": ";
  252.                 printMas(data);
  253.             }
  254.             countComp++;
  255.             data.mas[j] = tmp;
  256.             countSwap++;
  257.             std::cout << "h = " << h << ": ";
  258.             printMas(data);
  259.         }
  260.         std::cout << "h = " << h << ": ";
  261.         printMas(data);
  262.     }
  263.  
  264.     countPair.first = countSwap;
  265.     countPair.second = countComp;
  266.     return countPair;
  267. }
  268.  
  269. // ФУНКЦИЯ ДЛЯ ПОЛУЧЕНИЯ ВРЕМЕНИ, ЗАТРАЧЕННОГО НА ВЫПОЛНЕНИЕ СОРТИРОВКИ УКАЗАННЫМ ТИПОМ
  270. auto getRunTimeMS(DATA& data, type Type, std::pair<int, int>& countPair)
  271. {
  272.     std::chrono::steady_clock::time_point t_start, t_end;
  273.     if (Type == typeShakeSort)
  274.     {
  275.         t_start = std::chrono::high_resolution_clock::now();
  276.         countPair = ShakeSort(data);
  277.         t_end = std::chrono::high_resolution_clock::now();
  278.     }
  279.     if (Type == typeShellSort)
  280.     {
  281.         t_start = std::chrono::high_resolution_clock::now();
  282.         countPair = ShellSort(data);
  283.         t_end = std::chrono::high_resolution_clock::now();
  284.     }
  285.  
  286.     auto t_elapsed = std::chrono::duration <double>(t_end - t_start);
  287.     return t_elapsed.count() * 1000;
  288. }
  289.  
  290. int main()
  291. {
  292.     system("color F0");
  293.     ShowConsoleCursor(false);
  294.  
  295.     int ArrayCount = 0;
  296.     std::pair<int, int> countPair;
  297.     DATA data{ NULL, 9, 1, 100000 };
  298.     data.mas = new __int64[data.size];
  299.  
  300.     formRandArray(&data);
  301.  
  302.     std::cout << "ShellSort:\n\n";
  303.     countPair = ShellSortPrint(data);
  304.     std::cout << "\ncountSwap = " << countPair.first << " countComp = " << countPair.second << "\n\n";
  305.  
  306.     formRandArray(&data);
  307.  
  308.     std::cout << "\n--------------------------------\nShakeSort:\n\n";
  309.     countPair = ShakeSortPrint(data);
  310.     std::cout << "\ncountSwap = " << countPair.first << " countComp = " << countPair.second << "\n\n";
  311.  
  312.     delete[] data.mas;
  313.  
  314.     std::cout << "\n--------------------------------\n\n";
  315.  
  316.     ArrayCount = 5;
  317.     for (int i = 0; i < 7; i++)
  318.     {
  319.         __int64 ShakeSortComp = 0;
  320.         __int64 ShellSortComp = 0;
  321.         double  ShakeSortTime = 0.0;
  322.         double  ShellSortTime = 0.0;
  323.         __int64 ShakeSortSwap = 0;
  324.         __int64 ShellSortSwap = 0;
  325.  
  326.         std::cout << "n = " << 5000 + i * 7000 << ". Array count = " << ArrayCount << "\n\n";
  327.  
  328.         for (int j = 0; j < ArrayCount; j++)
  329.         {
  330.             countPair.first = 0;
  331.             countPair.second = 0;
  332.  
  333.             data.size = 5000 + i * 7000;
  334.             data.mas = new __int64[data.size];
  335.             formRandArray(&data);
  336.  
  337.             ShakeSortTime += getRunTimeMS(data, typeShakeSort, countPair);
  338.             ShakeSortSwap += countPair.first;
  339.             ShakeSortComp += countPair.second;
  340.  
  341.             delete[] data.mas;
  342.  
  343.             countPair.first = 0;
  344.             countPair.second = 0;
  345.  
  346.        
  347.             data.mas = new __int64[data.size];
  348.             formRandArray(&data);
  349.  
  350.             ShellSortTime += getRunTimeMS(data, typeShellSort, countPair);
  351.             ShellSortSwap += countPair.first;
  352.             ShellSortComp += countPair.second;
  353.  
  354.             delete[] data.mas;
  355.  
  356.             ShowConsoleCursor(false);
  357.             std::cout << ((j + 1) * 100) / ArrayCount << "% of arrays processed. \r" << std::flush;
  358.         }
  359.  
  360.         ShakeSortComp /= ArrayCount;
  361.         ShellSortComp /= ArrayCount;
  362.         ShakeSortSwap /= ArrayCount;
  363.         ShellSortSwap /= ArrayCount;
  364.         ShakeSortTime /= ArrayCount;
  365.         ShellSortTime /= ArrayCount;
  366.  
  367.         std::cout << "\n\n";
  368.         std::cout << "\tShakeSort:\n" << "\t\tAvgSwaps = " << ShakeSortSwap << "\tAvgComps = " << ShakeSortComp << "\tAvgTime = " << ShakeSortTime << " ms\n";
  369.         std::cout << "\tShellSort:\n" << "\t\tAvgSwaps = " << ShellSortSwap << "\tAvgComps = " << ShellSortComp << "\tAvgTime = " << ShellSortTime << " ms\n";
  370.         std::cout << "\n\n";
  371.     }
  372.  
  373.     return 0;
  374. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement