Bilim.techО проекте

Массивы, поиск и сортировка

Как быстро упорядочить парк машин по наработке и найти нужную? Сортируй пузырьком, вставками и быстрой сортировкой по шагам и сравни, сколько операций уходит у каждой.

01 Что это такое

Массив (список) это ряд пронумерованных ячеек. Сортировка расставляет их по порядку, а поиск находит нужную, и от способа зависит, сколько на это уйдет работы.

Наработку всех машин парка удобно держать в одном списке: часы = [6200, 7400, 5100, …]. К любой машине обращаются по номеру в квадратных скобках, и счет идет с нуля: часы[0] это первая машина. Чтобы составить очередь на ремонт, список сортируют. Самый простой способ, пузырек, сравнивает соседей и меняет их местами, но для большого парка он делает очень много сравнений. Быстрая сортировка делит список на части и справляется в разы быстрее. А в отсортированном списке нужную машину можно найти делением пополам, за несколько шагов вместо перебора всех.

6200часы[0]7400часы[1]5100часы[2]8900часы[3]7000часы[4]4300часы[5]5100 < 8900: стоят верно, не меняемномер ячейки (индекс) начинается с нуля
Столбик это наработка машины, под ним номер ячейки. Пузырек сравнивает пару соседей (выделены) и меняет их, если левый больше правого.
[i]
Индекс. Номер ячейки в квадратных скобках. Первая ячейка часы[0], последняя часы[n − 1], где n это длина списка.
n²
Медленный рост. Пузырек и вставки делают около n²/2 сравнений: для 10 машин 45, для 1000 уже полмиллиона.
n log n
Быстрый рост. Быстрая сортировка делает около n · log₂n сравнений: для 1000 машин около 10 000. Разница в 50 раз.
02 Опыт
Выбери способ. Запусти. Считай сравнения. ПАРК МАШИН
СОРТИРОВКА И ПОИСК

Очередь на ремонт по наработке

Рис. 12.4
ГОТОВЫЕ ПРОГРАММЫ
Сравнений элементов
Перестановок и сдвигов
Шагов программы
03 Код по строкам

Как работать со списком

Список, номер элемента и обмен двух ячеек: из этих трех приемов собраны все сортировки. Числа ниже берутся из опыта.

Как достать элемент?

часы[j]

Имя списка и номер в квадратных скобках. Номер может быть числом или выражением: часы[j + 1] это сосед справа. Если номер больше последнего, программа остановится с ошибкой.

часы
список наработки машин, ч
j
индекс, от 0 до длина(часы) − 1
длина(часы)
сколько элементов в списке, n

Как поменять местами?

а[i], а[j] = а[j], а[i]

Справа сначала берутся оба старых значения, потом они раскладываются по ячейкам слева. Без такой записи понадобилась бы третья переменная, иначе одно число потеряется.

а[i], а[j]
две ячейки, куда кладем
=
«положить в», сразу в обе
а[j], а[i]
значения, взятые до обмена

Сколько это стоит?

n(n − 1)/2 против n · log₂n

Пузырек сравнивает каждую пару: первый проход n − 1 сравнений, второй n − 2 и так далее. Быстрая сортировка делит список пополам около log₂n раз, и на каждом уровне просматривает все n элементов.

n
число элементов списка
log₂n
сколько раз n можно поделить пополам до единицы: log₂32 = 5
log₂n шагов
столько сравнений нужно двоичному поиску

Тот же код на настоящем Python

Справа программа из опыта на Python. Списки там пишутся так же, индексы тоже с нуля, а обмен a[i], a[j] = a[j], a[i] работает точно так же. Целочисленное деление // в двоичном поиске тоже из Python.

В настоящей работе сортировку не пишут руками: в Python есть sorted(часы) и часы.sort(), а в Excel кнопка «Сортировка». Внутри них стоит алгоритм порядка n · log n. Писать пузырек самому нужно, чтобы понять, откуда берется разница в скорости и почему программа, которая летала на 10 машинах, зависает на миллионе строк телеметрии.

Перевод делается автоматически из кода в опыте.
04 Где и зачем это применяют

Сортировка и поиск идут под капотом любой таблицы

Допущения модели+

Сравнением считается каждое сравнение, в котором участвует элемент списка (часы[j] > часы[j + 1], часы[j] > x); сравнения счетчиков вроде j >= 0 не считаются. Перестановкой считается каждая строка, которая записывает в список: обмен двух ячеек и сдвиг при вставке идут как одна операция. Быстрая сортировка взята в простом варианте с опорой в последнем элементе (схема Ломуто): на уже отсортированном списке она вырождается до n². Наработка машин сгенерирована случайно в пределах 3000–15000 ч, все значения разные. Замер роста гоняет готовые программы на случайных списках по одному разу.

Еще в направлении «Инженерия»

Все темы направления «Инженерия» →