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

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

.doc
Скачиваний:
0
Добавлен:
09.09.2026
Размер:
172 Кб
Скачать

МИНОБРНАУКИ РОССИИ

Санкт-Петербургский государственный

электротехнический университет

«ЛЭТИ» им. В. И. Ульянова (Ленина)

Кафедра МО ЭВМ

отчет

по лабораторной работе №2

по дисциплине «Алгоритмы и структуры данных»

Тема: Реализация и исследование алгоритма сортировки TimSort

Студентка гр. 2383

Бараева Е. Н.

Преподаватель

Гаврилов А. В.

Санкт-Петербург

2023

Цель работы.

Реализация и тестирование алгоритма сортировки Timsort, исследование данной сортировки на различных размерах данных, сравнение полученных результатов с теоретической оценкой.

Задание.

Реализация

Имеется массив данных для сортировки int arr[] размера n

Необходимо отсортировать его алгоритмом сортировки Timsort по следующему критерию: по наименьшему значению квадрата элемента (в случае равенства значений элементов в квадрате - сортировка происходит по убыванию).

Так как Timsort - это гибридный алгоритм, содержащий в себе сортировку слиянием и сортировку вставками, то вам предстоит использовать оба этих алгоритма. Поэтому нужно выводить разделённые блоки, которые уже отсортированы сортировкой вставками.

Исследование

После успешного решения задачи в рамках курса проведите исследование данной сортировки на различных размерах данных (10/1000/100000), сравнив полученные результаты с теоретической оценкой (для лучшего, среднего и худшего случаев), и разного размера min_run. Результаты исследования предоставьте в отчете.

Примечание:

Нельзя пользоваться готовыми библиотечными функциями для сортировки, нужно сделать реализацию сортировки вручную.

0 < n < 65

Обратите внимание на пример. (min_run = 32)

Формат входа.

Первая строка содержит натуральное число n - размерность массива, следующая строка содержит элементы массива через пробел.

Формат выхода.

Выводятся разделённые блоки для сортировки в формате "Part i: *отсортированный разделённый массив*"

Последняя строчка содержит финальный результат сортировки массива с надписью "Answer: ".

Выполнение работы.

Для реализации алгоритма Timsort были реализованы 3 функции: merge_sort, insertion_sort и Timsort.

Функция insertion_sort принимает изначальный массив, индекс начала подмассива и индекс конца подмассива. Далее делается проход от начала подмассива до конца, где запоминается сортируемый элемент и запоминается предыдущий индекс, затем сравниваются и переставляются элементы до тех пор, пока не будет выполнено условие сортировки. В конце сортируемый элемент вставляется в массив.

Функция merge_sort принимает массив с уже отсортированными подмассивами. Затем вызывается эта же функция для левой половины массива и для правой. Это происходит до тех пор, пока в левом и правом массивах не останется по 1 элементу. После создается временный массив, который станет отсортированным массивом из 2 маленьких массивов. Далее проходясь по элементам маленьких массивов, они сравниваются и кладутся во временный массив, где в конце временный массив переносится в исходный.

Функция Timsort принимает исходный массив, его длину и необязательный аргумент min_run для задания размера подмассивов. В функции производится проход по всему массиву с шагом в 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 большой, то сортировка вставкой существенно замедляет алгоритм сортировки, что также сказывается на времени работы программы.

ПРИЛОЖЕНИЕ А ИСХОДНЫЙ КОД ПРОГРАММЫ

Название файла: 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

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])

ПРИЛОЖЕНИЕ Б ГРАФИКИ

Рисунок 1 – малый набор данных

Рисунок 2 – средний набор данных

Рисунок 3 – большой набор данных

8

Соседние файлы в папке Лабы по АиСД 2023