Advertisement
igoryanchik

Merge and heap sort

Apr 12th, 2023 (edited)
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.64 KB | None | 0 0
  1. #include <iostream>
  2. #include <ctime>
  3. #include <random>
  4.  
  5. using namespace std;
  6.  
  7. //MergeSort
  8.  
  9. template <typename T>
  10. void merge(T* arr, int const left, int const right, int const mid)
  11. {
  12.     T* arrLeft = new T[mid - left + 1];//создаем доп.копию левой части массива, массив с началом в arr[left] и концом  в arr[mid - left]
  13.     for (int i = left; i < (mid + 1); ++i)
  14.     {
  15.         arrLeft[i - left] = arr[i]; //(1)так как left может не равняться нулю, а копируем мы элементы в пустой массив и нам надо присваивать начиная с нуля, то чтобы обращаться к нужному по порядку элементу в массиве arrLeft, вычитаем из и левую часть массива arr
  16.     }
  17.  
  18.     T* arrRight = new T[(right - mid)];//создаем доп.копию правой части массива,массив с началом в в arr[mid - left + 1] и концом в arr[right - mid]
  19.     for (int i = (mid + 1); i < (right + 1); ++i)
  20.     {
  21.         arrRight[(i - (mid + 1))] = arr[i]; // аналогично (1)
  22.     }
  23.  
  24.     int indexLeft = 0;
  25.     int indexRight = 0;
  26.     int indexRez = left;
  27.  
  28.     while (indexLeft < (mid - left + 1) && indexRight < (right - mid)) // пока один из сравниваемых массивов не кончился
  29.     {
  30.         if (arrLeft[indexLeft] <= arrRight[indexRight]) // cравниваем элементые двух подмассивов и выбираем меньший
  31.         {
  32.             arr[indexRez] = arrLeft[indexLeft];
  33.             indexLeft++;
  34.         }
  35.         else
  36.         {
  37.             arr[indexRez] = arrRight[indexRight];
  38.             indexRight++;
  39.         }
  40.         indexRez++;
  41.     }
  42.  
  43.     if (indexLeft >= (mid - left + 1)) //заполняем остаток arr тем, что осталось в непустом массиве
  44.     {
  45.         while (indexRight < (right - mid))
  46.         {
  47.             arr[indexRez] = arrRight[indexRight];
  48.             indexRight++;
  49.             indexRez++;
  50.         }
  51.     }
  52.     else
  53.     {
  54.         while (indexLeft < (mid - left + 1))
  55.         {
  56.             arr[indexRez] = arrLeft[indexLeft];
  57.             indexLeft++;
  58.             indexRez++;
  59.         }
  60.     }
  61.     delete[] arrLeft;
  62.     delete[] arrRight;
  63. }
  64.  
  65. template <typename T>
  66. void mergeSort(T* arr, int const left, int const right)
  67. {
  68.     if (left < 0 || right < 0 || left >= right) return;
  69.  
  70.     const int mid = (left + right) / 2;
  71.  
  72.     mergeSort(arr, left, mid); // левая часть массива
  73.     mergeSort(arr, mid + 1, right); // правая часть массива
  74.     merge(arr, left, right, mid); //отложенное дествие рекурсии, слияние вызывается, когда длина массива <= 1
  75. }
  76.  
  77. //HeapSort
  78.  
  79. template <class T>
  80. void filtrHeap(T* arr, int len, int index)
  81. {
  82.     int currentpos = index; // индекс элемента, который мы хотим правильно выставить в куче
  83.     T target = arr[currentpos]; // элмемент, который мы хотим правильно выставить в куче
  84.     int currChild = 2 * currentpos + 1;
  85.  
  86.     while (currChild < len) //пока у текущего элемента не окажется детей
  87.     {
  88.         if (currChild + 1 < len && arr[currChild + 1] >= arr[currChild]) currChild += 1; //выбираем максимум из дву детей
  89.  
  90.         if (target >= arr[currChild]) break; //все хорошо, куча под этим узлом выстроена верно
  91.         else    //иначе двигаем больший дочерний элемент вверх, а текущий элемент спускаем, определяя новую позицию элемента и его детей
  92.         {
  93.  
  94.             arr[currentpos] = arr[currChild];
  95.             currentpos = currChild;
  96.             currChild = 2 * currentpos + 1;
  97.         }
  98.     }
  99.     arr[currentpos] = target; // ставим элемент на законную позицию в куче
  100. }
  101.  
  102. template <class T>
  103. void heapBuild(T* arr, int n)
  104. {
  105.     int currnode = (n - 2) / 2;
  106.     while (currnode >= 0)//делаем из каждого узла - кучу
  107.     {
  108.         filtrHeap(arr, n, currnode);
  109.         currnode--;
  110.     }
  111. }
  112.  
  113. template <class T>
  114. void HeapSort(T* arr, int len)
  115. {
  116.     while (len > 0)
  117.     {
  118.         heapBuild(arr, len);
  119.         swap(arr[0], arr[len - 1]);
  120.         len--;
  121.     }
  122. }
  123.  
  124.  
  125.  
  126. template <typename T>
  127. void print(T* arr, int len)
  128. {
  129.     for (int i = 0; i < len; ++i)
  130.     {
  131.         cout << arr[i] << ' ';
  132.     }
  133. }
  134.  
  135. template <typename T>
  136. void fill(T* arr, int len)
  137. {
  138.     srand(time(NULL));
  139.  
  140.     for (int i = 0; i < len; ++i)
  141.     {
  142.         arr[i] = (rand()) % 70;
  143.     }
  144. }
  145.  
  146. int main()
  147. {
  148.     int a[20];
  149.     fill(a, 20);
  150.  
  151.     mergeSort(a, 0, 19);
  152.  
  153.     print(a, 20);
  154.  
  155.     cout << '\n';
  156.  
  157.     HeapSort(a, 20);
  158.  
  159.     print(a, 20);
  160.  
  161.     return 0;
  162. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement