Визуализация
Данные: Случайные
Легенда цветов
Как работает сортировка Шелла
Идея алгоритма. Сортировка вставками отлично работает на почти отсортированных массивах, но чудовищно медленна, если маленький элемент находится в самом конце - ему приходится сдвигаться на 1 позицию за раз. Сортировка Шелла решает эту проблему: она позволяет обменивать элементы, находящиеся далеко друг от друга.
Суть метода: Мы выбираем некий шаг gap (например, половину длины массива) и сортируем вставками элементы, отстоящие друг от друга на этот шаг. В результате массив становится "частично отсортированным".
Уменьшение шага: На следующем этапе шаг gap уменьшается (например, делится еще надвое), и процесс повторяется. Так элементы быстрее "перепрыгивают" большие расстояния к своим правильным позициям.
Последний проход (gap = 1): Когда шаг становится равен единице, алгоритм превращается в обычную сортировку вставками. Но поскольку массив уже почти отсортирован на предыдущих этапах с большим gap, этот финальный проход работает очень быстро.
Синонимы названия: сортировка Шелла, Shell Sort, сортировка с убывающим шагом.
Сложность алгоритма
Сложность зависит от того, какую последовательность шагов gap мы выберем. Классическая последовательность (деление на 2: n/2, n/4, ..., 1) не является оптимальной.
По времени
Показывает, как растет число операций (сравнений и сдвигов/обменов) при росте n. Лейбл "Сложность по времени" под визуализацией показывает общую оценку для классической версии.
| Случай | Время | Комментарий |
|---|---|---|
| Лучший случай | O(n log n) | Массив уже отсортирован. |
| Средний случай | O(n^1.5) | Зависит от шагов. С последовательностью Хиббарда или Кнута сложность лучше O(n²). |
| Худший случай | O(n^2) | Для классической последовательности n/2, если элементы на нечетных позициях больше элементов на четных. |
По памяти
Показывает, сколько дополнительной памяти нужно алгоритму.
| Характеристика | Оценка | Комментарий |
|---|---|---|
| Дополнительная память | O(1) | Сортировка происходит "на месте" (in-place), элементы меняются местами внутри самого массива. |
Устойчивость алгоритма
Устойчивой называется сортировка, которая не меняет взаимный порядок равных элементов.
| Характеристика | Оценка | Комментарий |
|---|---|---|
| Устойчивость | Нет | Равные элементы могут быть переставлены, так как обмены происходят на больших расстояниях (gap > 1). |
Примеры реализации сортировки Шелла (Shell Sort)
Код на C
void shellSort(int arr[], int n) {
// Начинаем с большого шага, уменьшаем его вдвое на каждой итерации
for (int gap = n/2; gap > 0; gap /= 2) {
// Выполняем сортировку вставками для текущего шага
for (int i = gap; i < n; i++) {
int temp = arr[i];
int j;
// Сдвигаем элементы, пока они больше temp
for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
arr[j] = arr[j - gap];
}
arr[j] = temp;
}
}
}
Код на Python
def shell_sort(arr):
n = len(arr)
gap = n // 2
# Пока шаг больше нуля
while gap > 0:
for i in range(gap, n):
temp = arr[i]
j = i
# Сдвигаем элементы на расстояние gap
while j >= gap and arr[j - gap] > temp:
arr[j] = arr[j - gap]
j -= gap
arr[j] = temp
gap //= 2
Код на JavaScript
function shellSort(arr) {
let n = arr.length;
// Делим шаг на 2 на каждой итерации
for (let gap = Math.floor(n / 2); gap > 0; gap = Math.floor(gap / 2)) {
for (let i = gap; i < n; i++) {
let temp = arr[i];
let j = i;
// Вставляем элемент на правильную позицию среди элементов с шагом gap
while (j >= gap && arr[j - gap] > temp) {
arr[j] = arr[j - gap];
j -= gap;
}
arr[j] = temp;
}
}
return arr;
}
Хотите разобрать тему глубже? В нашем бесплатном курсе есть урок про сортировку Шелла - с подробной теорией, задачами и проверочными вопросами.