4 курс / СиАОД пример 1 (1)
.docxФедеральное агентство связи
Ордена Трудового Красного Знамени
Федеральное государственное бюджетное образовательное учреждение высшего образования
«Московский технический университет связи и информатики»
Кафедра Математической Кибернетики и Информационных Технологий
Отчет по лабораторной работе
по предмету «СиАОД»
на тему:
«Методы сортировки»
Выполнил: студент группы ____
______
Руководитель:
Кутейников Иван Алексеевич
Москва 2021
Цель работы
Реализовать заданный метод сортировки числовой матрицы в соответствии с индивидуальным заданием. Для всех вариантов добавить реализацию быстрой сортировки (quicksort). Оценить время работы каждого алгоритма сортировки и сравнить его со временем стандартной функции сортировки, используемой в выбранном языке программирования.
Вариант 10
Сортировка Шелла (Shell sort)
Ход работы
В соответствии с заданием, реализовали алгоритм быстрой сортировки на языке C++:
template<class Iter>
Iter partition(Iter first, Iter last)
{
Iter pivot = last - 1;
Iter right = first;
for (auto unknown = first; unknown != last - 1; ++unknown)
{
if (*unknown <= *pivot)
{
std::iter_swap(right, unknown);
++right;
}
}
std::iter_swap(right, pivot);
return right;
}
template<class Iter>
void quick_sort(Iter first, Iter last)
{
if (std::distance(first, last) > 1)
{
auto q = partition(first, last);
quick_sort(first, q);
quick_sort(q + 1, last);
}
}
Также, реализовали алгоритм сортировки Шелла:
template<typename it, typename compare>
void shell(it start, it end, compare comp) {
for (auto step = (end - start) / 2; step > 0; step /= 2) {
for (auto i = start + step; i < end; i++) {
for (auto j = i; j - start >= step && comp(*j, *(j - step)); j -= step)
std::swap(*j, *(j - step));
}
}
}
Сравнение времени выполнения алгоритмов, для массива размером 100000:
n |
Shell Sort,мс |
std::sort,мс |
Quick Sort,мс |
1 |
47.503 |
27.703 |
27.651 |
2 |
49.567 |
29.797 |
27.789 |
3 |
59.568 |
34.877 |
30.658 |
4 |
47.735 |
27.36 |
29.218 |
5 |
59.28 |
27.66 |
26.772 |
Среднее время выполнения каждого из алгоритмов:
Shell Sort – 52.73мс
std::sort – 29.479мс
Quick sort – 28.418мс
Как можно видеть, наилучший результат показала быстрая сортировка, но это может быть из-за того, что массив не слишком велик, и с увеличением количества тестов, какая-то из остальных сортировок покажет лучший результат.
Сравнение времени выполнения алгоритмов, для массива размером 1000000:
n |
Shell Sort,мс |
std::sort,мс |
Quick Sort,мс |
1 |
868.642 |
370.057 |
400.685 |
2 |
719.506 |
272.312 |
308.089 |
3 |
922.379 |
452.365 |
500.553 |
4 |
929.886 |
481.789 |
472.754 |
5 |
1026.45 |
470.904 |
578.926 |
Среднее время выполнения каждого из алгоритмов:
Shell Sort – 879.773мс
std::sort – 409.485мс
Quick Sort – 452.201мс
При большем размере массива, наилучший результат показала встроенная сортировка C++, а наихудший - Shell Sort.
Обращаем внимание на то, что при сортировках использовался одинаковый массив случайно сгенерированных чисел
Код программы
#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>
#include "Timer.h"
#ifdef _DEBUG
#include "MemoryLeakTracker.h"
#endif
// сортировка Шелла
template<typename it, typename compare>
void shell(it start, it end, compare comp) {
for (auto step = (end - start) / 2; step > 0; step /= 2) {
for (auto i = start + step; i < end; i++) {
for (auto j = i; j - start >= step && comp(*j, *(j - step)); j -= step)
std::swap(*j, *(j - step));
}
}
}
// разбиение массива на две части относительно опорного элемента
// (для самодельной быстрой сортировки)
template<class Iter>
Iter partition(Iter first, Iter last)
{
Iter pivot = last - 1;
Iter right = first;
for (auto unknown = first; unknown != last - 1; ++unknown)
{
if (*unknown <= *pivot)
{
std::iter_swap(right, unknown);
++right;
}
}
std::iter_swap(right, pivot);
return right;
}
// самодельная быстрая сортировка
template<class Iter>
void quick_sort(Iter first, Iter last)
{
if (std::distance(first, last) > 1)
{
auto q = partition(first, last);
quick_sort(first, q);
quick_sort(q + 1, last);
}
}
int main() {
std::cout << "Enter array size" << std::endl;
int size;
srand(time(0));
std::cin >> size;
std::cout << std::endl;
std::cout << "Elements in array: " << size << std::endl;
std::cout << std::endl;
std::vector<int> vec(size);
std::generate(vec.begin(), vec.end(), std::rand);
#ifdef _DEBUG
for (int el : vec)
{
std::cout << el << " ";
}
#endif
std::vector<int> vec2(size);
std::vector<int> vec3(size);
std::copy(vec.begin(), vec.end(), vec2.begin());
std::copy(vec.begin(), vec.end(), vec3.begin());
{
Timer time("Shell sort");
shell(vec.begin(), vec.end(), [](int a, int b) { return a < b; });
}
{
Timer time("Built-in quick sort (std::sort)");
std::sort(vec2.begin(), vec2.end(), [](int a, int b) { return a < b; });
}
{
Timer time("Custom quick sort");
quick_sort(vec3.begin(), vec3.end());
}
}
Вывод
При меньшем размере массива быстрая сортировка показала лучший результат, но не намного быстрее остальных. При больше размере массива, лучший результат показала встроенная сортировка, затем с небольшим отставанием быстрая сортировка и наихудший, с довольно большим отставанием по времени – сортировка Шелла.
