diff --git a/README.md b/README.md index 55766c0..9417cc6 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ ## 1. Информация о студенте -**Номер группы**: 00-000 +**Номер группы**: 11-109 -**Фамилия и Имя**: Иванов Иван +**Фамилия и Имя**: Шамсутдинов Рафаэль ## 2. Описание задания diff --git a/src/heap_sort.cpp b/src/heap_sort.cpp index d57f66c..32eece8 100644 --- a/src/heap_sort.cpp +++ b/src/heap_sort.cpp @@ -8,11 +8,14 @@ namespace assignment { void HeapSort::Sort(std::vector& arr) const { // строим двоичную кучу ... BuildMaxHeap ... + BuildMaxHeap(arr); // обходим элементы кучи с конца до корня (не включительно) for (int index = static_cast(arr.size()) - 1; index > 0; index--) { // обмениваем местами корень (максимальный элемент) и последний элемент кучи ... std::swap ... + std::swap(arr[0], arr[index]); // спускаем новый корневой узел вниз ... Heapify ... + Heapify(arr, index, 0); } } @@ -26,6 +29,11 @@ namespace assignment { const int size = static_cast(arr.size()); // Напишите здесь свой код ... + if (size == 0) return; + + for (int index = Parent(size - 1); index >= 0; index--) { + Heapify(arr, size, index); + } } void HeapSort::Heapify(std::vector& arr, int heap_size, int index) { @@ -39,6 +47,12 @@ namespace assignment { const int right_child = RightChild(index); // поиск наибольшего элемента среди текущего элемента и его потомков ... + if (left_child < heap_size && arr[largest] < arr[left_child]) { + largest = left_child; + } + if (right_child < heap_size && arr[largest] < arr[right_child]) { + largest = right_child; + } // если текущий элемент больше своих потомков, то он находится на правильном месте (свойство макс. кучи) if (largest == index) { @@ -46,9 +60,10 @@ namespace assignment { } // обмениваем местами текущий элемент с его потомком ... std::swap ... + std::swap(arr[largest], arr[index]); // продолжаем спуск c нового места (после операции обмена местами) - index = -1 /* здесь какая-то ошибка ... */; + index = largest /* здесь какая-то ошибка ... */; } } @@ -67,4 +82,4 @@ namespace assignment { return 2 * index + 2; } -} // namespace assignment +} // namespace assignment \ No newline at end of file diff --git a/src/insertion_sort.cpp b/src/insertion_sort.cpp index f0c182f..cee061c 100644 --- a/src/insertion_sort.cpp +++ b/src/insertion_sort.cpp @@ -2,6 +2,10 @@ #include // move, swap +#include "assignment/insertion_sort.hpp" + +#include // move, swap + #include "assignment/partitioning.hpp" // middle_of namespace assignment { @@ -9,37 +13,42 @@ namespace assignment { int linear_search(const std::vector& arr, int index) { // итерация всех предыдущих элементов [0, index - 1] (они находятся в отсортированном порядке) - for (int curr_pos = -1 /* ... */; false /* условие ... */; /* обновление curr_pos ... */) { - + for (int curr_pos = 0; curr_pos < index; curr_pos++) { + if (arr[curr_pos] >= arr[index]) return curr_pos; // если текущий элемент меньше или равен вставляемому, позиция для вставки найдена ... } - return -1; // здесь что-то не так ... + return index; // здесь что-то не так ... } int binary_search(const std::vector& arr, int index) { // начало, конец и середина области поиска места для вставки [0, index - 1] - int start = -1 /* здесь что-то не так ... */; - int stop = -1 /* здесь что-то не так ... */; - int middle = -1 /* здесь что-то не так ... */; + int start = 0 /* здесь что-то не так ... */; + int stop = index - 1 /* здесь что-то не так ... */; + int middle = middle_of(start, stop) /* здесь что-то не так ... */; // ищем до тех пор, пока границы не схлопнулись while (start <= stop) { // возвращаем позицию для вставки if (arr[index] == arr[middle]) { - return -1 /* здесь что-то не так ... */; + return middle /* здесь что-то не так ... */; } // обновляем границы области поиска ... + if (arr[index] < arr[middle]) { + stop = middle - 1; + } else { + start = middle + 1; + } // обновляем середину области поиска - middle = middle_of(-1, -1); // здесь что-то не так ... + middle = middle_of(start, stop); // здесь что-то не так ... } // в конечном счете возвращаем начало последней области поиска - return -1; // здесь что-то не так ... + return start; // здесь что-то не так ... } void InsertionSort::Sort(std::vector& arr) const { @@ -52,6 +61,12 @@ namespace assignment { // поиск индекса для вставки элемента с индексом index в область [0, index - 1] const int ins_index = searcher_(arr, index); + if (index == ins_index) continue; + int num = arr[index]; + for (unsigned long long int i = index; i > ins_index; i--) { + arr[i] = arr[i - 1]; + } + arr[ins_index] = num; // если индекс вставки не совпадает с текущей позицией элемента, // производим вставку элемента на вычисленную позицию (std::copy или цикл for) ... } diff --git a/src/merge_sort.cpp b/src/merge_sort.cpp index c6ad3ab..b0b93d4 100644 --- a/src/merge_sort.cpp +++ b/src/merge_sort.cpp @@ -10,7 +10,7 @@ namespace assignment { // буфер памяти для операции слияния (merge) std::vector buf(arr.size()); - // забыл что-то здесь вызвать ... + merge_sort(arr, 0, static_cast(arr.size() - 1), buf); } void MergeSort::merge_sort(std::vector& arr, int start, int stop, std::vector& buf) const { @@ -23,8 +23,12 @@ namespace assignment { // вычисляем индекс середины области const int middle = middle_of(start, stop); + merge_sort(arr, start, middle, buf); + merge_sort(arr, middle + 1, stop, buf); + merge(arr, start, middle, stop, buf); + // рекурсивный вызов сортировки левой [start, middle] и правой [middle + 1, stop] подмассивов ... // слияния двух подмассивов [start, middle] и [middle + 1, stop] ... } -} // namespace assignment +} // namespace assignment \ No newline at end of file diff --git a/src/merging.cpp b/src/merging.cpp index b5e49d7..0d6476e 100644 --- a/src/merging.cpp +++ b/src/merging.cpp @@ -13,13 +13,19 @@ namespace assignment { int right_offset = middle + 1; // индекс текущей позиции буфера (туда будут сливаться подмассивы) - int buf_offset = -1 /* здесь что-то не так */; + int buf_offset = 0/* здесь что-то не так */; // слияния подмассивов (пока не достигли конца одного из подмассивов) while (left_offset <= middle && right_offset <= stop) { // копируем элемент с наименьшим значением в буфер ... - + if (arr[left_offset] <= arr[right_offset]) { + buf[buf_offset] = arr[left_offset]; + left_offset++; + } else { + buf[buf_offset] = arr[right_offset]; + right_offset++; + } // перемещаем текущую позицию вставки в буфер buf_offset += 1; } @@ -31,7 +37,14 @@ namespace assignment { } // реализуйте сливание остатков правого подмассива ... + for ( ; right_offset <= stop; right_offset++) { + buf[buf_offset] = arr[right_offset]; + buf_offset++; + } + for (int i = 0; i < buf_offset; i++) { + arr[start + i] = buf[i]; + } // копируем результат слияния подмассивов из буфера в оригинальный массив ... std::copy или цикл for ... } diff --git a/src/partitioning.cpp b/src/partitioning.cpp index e706327..98d5a1e 100644 --- a/src/partitioning.cpp +++ b/src/partitioning.cpp @@ -21,10 +21,25 @@ namespace assignment { const int middle = middle_of(start, stop); // поиск медианы среди трех элементов по индексам start, middle и stop + if (arr[start] >= arr[middle]) { + if (arr[middle] >= arr[stop]) { + return middle; + } + if (arr[start] >= arr[stop]) { + return stop; + } + return start; + } - // Здесь должна быть ваша реализация ... + if (arr[start] >= arr[stop]) { + return start; + } + if (arr[stop] < arr[middle]) { + return stop; + } + return middle; - return -1 /* здесь что-то не так ... */; + // Здесь должна быть ваша реализация ... } int partition(std::vector& arr, int start, int stop, int pivot) { @@ -52,7 +67,8 @@ namespace assignment { for (int index = start; index < stop; index++) { if (arr[index] < pivot_value) { - // Напишите здесь ваш код ... + std::swap(arr[curr_pivot_index], arr[index]); + curr_pivot_index++; } } @@ -60,7 +76,7 @@ namespace assignment { std::swap(arr[curr_pivot_index], arr[stop]); // возвращаем индекс опорного элемента - return -1 /* здесь что-то не так ... */; + return curr_pivot_index /* здесь что-то не так ... */; } } // namespace assignment \ No newline at end of file diff --git a/src/quick_sort.cpp b/src/quick_sort.cpp index 202e6d4..8fa8bb1 100644 --- a/src/quick_sort.cpp +++ b/src/quick_sort.cpp @@ -18,10 +18,13 @@ namespace assignment { } // вычисляем индекс опорного элемента ... median_of_three ... - int pivot_index = -1 /* напишите здесь свой код ... */; + int pivot_index = median_of_three(arr, start, stop) /* напишите здесь свой код ... */; + pivot_index = partition(arr, start, stop, pivot_index); + quick_sort(arr, start, pivot_index - 1); + quick_sort(arr, pivot_index + 1, stop); // производим разбиение относительно опорного элемента ... partition ... // рекурсивно повторяем процедуру над левой и правой частью ... } -} // namespace assignment +} // namespace assignment \ No newline at end of file