Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабы по АиСД 2023 / Baraeva_Elizaveta_lb2

.pdf
Скачиваний:
0
Добавлен:
09.09.2026
Размер:
282 Кб
Скачать
МИНОБРНАУКИ РОССИИ
САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ
ЭЛЕКТРОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
«ЛЭТИ» ИМ. В. И. УЛЬЯНОВА (ЛЕНИНА)
Кафедра МО ЭВМ
ОТЧЕТ
по дисциплине «Алгоритмы и структуры данных»
Тема: Реализация и исследование алгоритма сортировки TimSort
Студентка гр. 2383
Бараева Е. Н.
Преподаватель
Гаврилов А. В.
Санкт-Петербург
2023
2
Цель работы.
Реализация и тестирование алгоритма сортировки Timsort, исследование данной сортировки на различных размерах данных, сравнение полученных результатов с теоретической оценкой.
Задание.
Реализация
Имеется массив данных для сортировки int arr[] размера n
Необходимо отсортировать его алгоритмом сортировки Timsort по
следующему критерию: по наименьшему значению квадрата элемента (в
случае равенства значений элементов в квадрате - сортировка происходит по убыванию).
Так как Timsort - это гибридный алгоритм, содержащий в себе
сортировку слиянием и сортировку вставками, то вам предстоит использовать
оба этих алгоритма. Поэтому нужно выводить разделённые блоки, которые
уже отсортированы сортировкой вставками.
Исследование
После успешного решения задачи в рамках курса проведите
исследование данной сортировки на различных размерах данных
(10/1000/100000), сравнив полученные результаты с теоретической оценкой
(для лучшего, среднего и худшего случаев), и разного размера min_run. Результаты исследования предоставьте в отчете.
Примечание:
Нельзя пользоваться готовыми библиотечными функциями для
сортировки, нужно сделать реализацию сортировки вручную.
0 < n < 65
Обратите внимание на пример. (min_run = 32)
3
Формат входа.
Первая строка содержит натуральное число n - размерность массива, следующая строка содержит элементы массива через пробел.
Формат выхода.
Выводятся разделённые блоки для сортировки в формате "Part i:
*отсортированный разделённый массив*"
Последняя строчка содержит финальный результат сортировки массива с
надписью "Answer: ".
Выполнение работы.
Для реализации алгоритма Timsort были реализованы 3 функции: merge_sort, insertion_sort и Timsort.
Функция insertion_sort принимает изначальный массив, индекс начала подмассива и индекс конца подмассива. Далее делается проход от начала подмассива до конца, где запоминается сортируемый элемент и запоминается предыдущий индекс, затем сравниваются и переставляются элементы до тех
пор, пока не будет выполнено условие сортировки. В конце сортируемый
элемент вставляется в массив.
Функция merge_sort принимает массив с уже отсортированными подмассивами. Затем вызывается эта же функция для левой половины
массива и для правой. Это происходит до тех пор, пока в левом и правом
массивах не останется по 1 элементу. После создается временный массив,
который станет отсортированным массивом из 2 маленьких массивов. Далее проходясь по элементам маленьких массивов, они сравниваются и кладутся во временный массив, где в конце временный массив переносится в исходный.
Функция Timsort принимает исходный массив, его длину и необязательный аргумент min_run для задания размера подмассивов. В
4
функции производится проход по всему массиву с шагом в min_run. В цикле вычисляется индекс начала и конца помассива и вызывается функция insertion_sort для сортировки подмассивов методом вставки. Далее этот подмассив выводится. После цикла вызывается функция merge_sort, которая
сортирует весь массив методом слияния. В конце выводится
отсортированный массив.
Разработанный программный код см. в приложении А.
Тестирование.
Результаты тестирования представлены в табл. 1. Таблица 1 – Результаты тестирования
п/п
Входные данные
Выходные данные
Комментарии
1.
44
-4 7 5 3 5 -4 2 -1 -9 ­8 -3 0 9 -7 -4 -10 -4 2 6 1 -2 -3 -1 -8 0 -8 -7
-3 5 -1 -8 -8 8 -1 -3 3 6 1 -8 -1 3 -9 9 -6
Part 0: 0 0 1 -1 -1 -1 2 2 -2 3 -3 -3
-3 -4 -4 -4 -4 5 5 5 6 7 -7 -7 -8 -8 ­8 -8 -8 9 -9 -10 Part 1: 1 -1 -1 3 3 -3 6 -6 8 -8 9 -9 Answer: 0 0 1 1 -1 -1 -1 -1 -1 2 2 ­2 3 3 3 -3 -3 -3 -3 -4 -4 -4 -4 5 5 5 6 6 -6 7 -7 -7 8 -8 -8 -8 -8 -8 -8 9 9 -9 -9 -10
Проверка
сортировки. Верно.
2.
19
-5 -1 6 -6 0 -4 7 -2 -2 9 -2 -10 5 8 3 2 2 8 9
Part 0: 0 -1 2 2 -2 -2 -2 3 -4 5 -5 6
-6 7 8 8 9 9 -10 Answer: 0 -1 2 2 -2 -2 -2 3 -4 5 -5 6 -6 7 8 8 9 9 -10
Проверка
сортировки. Верно.
3.
10
-1 -1 -1 -1 1 -1 -1 -1 ­1 1
Part 0: 1 1 -1 -1 -1 -1 -1 -1 -1 -1 Answer: 1 1 -1 -1 -1 -1 -1 -1 -1 -1
Проверка
сортировки. Верно.
Вывод.
Был реализован и исследован алгоритм сортировки Timsort. Если размер min_run слишком мал, то теряется эффективность алгоритма, т. к. он превращается в алгоритм сортировки слиянием. Если же размер min_run
большой, то сортировка вставкой существенно замедляет алгоритм
сортировки, что также сказывается на времени работы программы.
5
ПРИЛОЖЕНИЕ А
ИСХОДНЫЙ КОД ПРОГРАММЫ
Название файла: main.py
import math
def merge_sort(array):
if len(array) == 1 or len(array) == 0:
return array
left_array = merge_sort(array[:math.ceil(len(array) / 2)])
right_array = merge_sort(array[math.ceil(len(array) / 2):])
left_index = right_index = counter = 0
temporary = [0] * (len(left_array) + len(right_array))
while left_index < len(left_array) and right_index < len(right_array):
if abs(right_array[right_index]) == abs(left_array[left_index]) and right_array[right_index] > left_array[left_index] or abs(right_array[right_index]) < abs(left_array[left_index]):
temporary[counter] = right_array[right_index]
right_index += 1
else:
temporary[counter] = left_array[left_index]
left_index += 1
counter += 1
while left_index < len(left_array):
temporary[counter] = left_array[left_index]
left_index += 1
counter += 1
while right_index < len(right_array):
temporary[counter] = right_array[right_index]
right_index += 1
counter += 1
for i in range(len(array)):
array[i] = temporary[i]
return array
def insertion_sort(array, start, end):
for i in range(start + 1, end):
value = array[i]
j = i - 1
while j >= start and (abs(value) == abs(array[j]) and value > array[j] or abs(value) < abs(array[j])):
array[j + 1] = array[j]
j -= 1
array[j + 1] = value
def Timsort(array, len_array, min_run=32):
part = 0
for i in range(0, len_array, min_run):
start = i
end = i + min_run if (i + min_run <= len_array) else len_array
6
insertion_sort(array, start, end)
string = ''
for j in range(start, end):
string += ' ' + str(array[j])
print(f'Part {part}:{string}')
part += 1
merge_sort(array)
print('Answer: {}'.format(' '.join(map(str, array))))
n = int(input())
arr = list(map(int, input().split()))
Timsort(arr, n)
Название файла: test.py
import main
def test_sorted():
arr = [1, 2, 3, 4, 5, 6, 7, 8]
main.Timsort(arr, 8)
assert (arr == [1, 2, 3, 4, 5, 6, 7, 8])
def test_none():
arr = []
main.Timsort(arr, 0)
assert (arr == [])
def test_reverse():
arr = [5, 4, 3, 2, 1, 0, -1, -2, -3, -4]
main.Timsort(arr, 10)
assert (arr == [0, 1, -1, 2, -2, 3, -3, 4, -4, 5])
def test_mixed():
arr = [9, -84, 38, 4, -3, 90, -2, 0, 8, 45, 99, 0, 9, 0, -2]
main.Timsort(arr, 8)
assert (arr == [0, 0, 0, -2, -2, -3, 4, 8, 9, 9, 38, 45, -84, 90, 99])
7
ПРИЛОЖЕНИЕ Б
ГРАФИКИ
Рисунок 1 – малый набор данных
Рисунок 2 – средний набор данных
8
Рисунок 3 – большой набор данных
Соседние файлы в папке Лабы по АиСД 2023