Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <ctime>
- #include <random>
- using namespace std;
- //MergeSort
- template <typename T>
- void merge(T* arr, int const left, int const right, int const mid)
- {
- T* arrLeft = new T[mid - left + 1];//создаем доп.копию левой части массива, массив с началом в arr[left] и концом в arr[mid - left]
- for (int i = left; i < (mid + 1); ++i)
- {
- arrLeft[i - left] = arr[i]; //(1)так как left может не равняться нулю, а копируем мы элементы в пустой массив и нам надо присваивать начиная с нуля, то чтобы обращаться к нужному по порядку элементу в массиве arrLeft, вычитаем из и левую часть массива arr
- }
- T* arrRight = new T[(right - mid)];//создаем доп.копию правой части массива,массив с началом в в arr[mid - left + 1] и концом в arr[right - mid]
- for (int i = (mid + 1); i < (right + 1); ++i)
- {
- arrRight[(i - (mid + 1))] = arr[i]; // аналогично (1)
- }
- int indexLeft = 0;
- int indexRight = 0;
- int indexRez = left;
- while (indexLeft < (mid - left + 1) && indexRight < (right - mid)) // пока один из сравниваемых массивов не кончился
- {
- if (arrLeft[indexLeft] <= arrRight[indexRight]) // cравниваем элементые двух подмассивов и выбираем меньший
- {
- arr[indexRez] = arrLeft[indexLeft];
- indexLeft++;
- }
- else
- {
- arr[indexRez] = arrRight[indexRight];
- indexRight++;
- }
- indexRez++;
- }
- if (indexLeft >= (mid - left + 1)) //заполняем остаток arr тем, что осталось в непустом массиве
- {
- while (indexRight < (right - mid))
- {
- arr[indexRez] = arrRight[indexRight];
- indexRight++;
- indexRez++;
- }
- }
- else
- {
- while (indexLeft < (mid - left + 1))
- {
- arr[indexRez] = arrLeft[indexLeft];
- indexLeft++;
- indexRez++;
- }
- }
- delete[] arrLeft;
- delete[] arrRight;
- }
- template <typename T>
- void mergeSort(T* arr, int const left, int const right)
- {
- if (left < 0 || right < 0 || left >= right) return;
- const int mid = (left + right) / 2;
- mergeSort(arr, left, mid); // левая часть массива
- mergeSort(arr, mid + 1, right); // правая часть массива
- merge(arr, left, right, mid); //отложенное дествие рекурсии, слияние вызывается, когда длина массива <= 1
- }
- //HeapSort
- template <class T>
- void filtrHeap(T* arr, int len, int index)
- {
- int currentpos = index; // индекс элемента, который мы хотим правильно выставить в куче
- T target = arr[currentpos]; // элмемент, который мы хотим правильно выставить в куче
- int currChild = 2 * currentpos + 1;
- while (currChild < len) //пока у текущего элемента не окажется детей
- {
- if (currChild + 1 < len && arr[currChild + 1] >= arr[currChild]) currChild += 1; //выбираем максимум из дву детей
- if (target >= arr[currChild]) break; //все хорошо, куча под этим узлом выстроена верно
- else //иначе двигаем больший дочерний элемент вверх, а текущий элемент спускаем, определяя новую позицию элемента и его детей
- {
- arr[currentpos] = arr[currChild];
- currentpos = currChild;
- currChild = 2 * currentpos + 1;
- }
- }
- arr[currentpos] = target; // ставим элемент на законную позицию в куче
- }
- template <class T>
- void heapBuild(T* arr, int n)
- {
- int currnode = (n - 2) / 2;
- while (currnode >= 0)//делаем из каждого узла - кучу
- {
- filtrHeap(arr, n, currnode);
- currnode--;
- }
- }
- template <class T>
- void HeapSort(T* arr, int len)
- {
- while (len > 0)
- {
- heapBuild(arr, len);
- swap(arr[0], arr[len - 1]);
- len--;
- }
- }
- template <typename T>
- void print(T* arr, int len)
- {
- for (int i = 0; i < len; ++i)
- {
- cout << arr[i] << ' ';
- }
- }
- template <typename T>
- void fill(T* arr, int len)
- {
- srand(time(NULL));
- for (int i = 0; i < len; ++i)
- {
- arr[i] = (rand()) % 70;
- }
- }
- int main()
- {
- int a[20];
- fill(a, 20);
- mergeSort(a, 0, 19);
- print(a, 20);
- cout << '\n';
- HeapSort(a, 20);
- print(a, 20);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement