Алгоритм сортировки Шелла с примером

⚡ Умное резюме

Сортировка Шелла — это алгоритм сравнения на месте, который обобщает сортировку вставками, сравнивая элементы, расположенные на значительном расстоянии друг от друга, а затем уменьшая это расстояние до тех пор, пока соседние элементы не будут отсортированы.

  • 📊 Определение: Обобщение алгоритма сортировки вставками, предложенного Дональдом Шеллом в 1959 году, использующее убывающую последовательность пропусков.
  • 🔀 Последовательности пробелов: Оригинальная последовательность Шелла — n/2, n/4, …, 1; последовательности Кнута, Седжвика и Чиуры на практике показывают лучшие результаты.
  • Сложность: В лучшем случае O(n log n), в худшем случае O(n^2) и в дополнительном пространстве O(1).
  • Случаи использования: Ядро Linux, библиотека uClibc и пакет bzip2 используют алгоритм сортировки Shell Sort для предотвращения рекурсии и использования дополнительной памяти стека.
  • 🤖 Под углом к ​​искусственному интеллекту: Искусственный интеллект-ассистенты могут предлагать последовательности пропусков и генерировать анимированные визуализации алгоритма сортировки Шелла по запросу.

Что такое сортировка Шелла?

Сортировка Шелла, также называемая методом Шелла, — это эффективный алгоритм сортировки на месте, основанный на сравнении. Названный в честь Дональда Шелла, который представил эту идею в 1959 году, он представляет собой обобщенное расширение сортировки вставками, преодолевающее ее квадратичное поведение на разрозненных данных.

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

Этот промежуток, интервал, следует выбранной последовательности, такой как оригинальная последовательность Шелла, Кнута, Хиббарда или Седжвика. Оригинальная последовательность Шелла — это n/2, n/4, ..., 1.

Алгоритм сортировки Шелла

Шаг 1) Инициализируйте интервальное значение h = n/2, где n — размер массива.

Шаг 2) Поместите все элементы, находящиеся на расстоянии, равном интервалу h, в подсписок.

Шаг 3) Отсортируйте каждый подсписок с помощью сортировки вставками.

Шаг 4) Установите новый интервал h = h/2.

Шаг 5) Если h > 0, вернитесь к шагу 2. В противном случае перейдите к шагу 6.

Шаг 6) Полученный массив теперь полностью отсортирован.

Как работает сортировка Шелла

При сортировке вставками элементы перемещаются только на одну позицию за раз. Сортировка Шелла, напротив, делит массив на подсписки с большим интервалом и применяет сортировку вставками к каждому подсписку.

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

Сортировка Шеллом работает

Принцип работы алгоритма сортировки Шелла на примере.

Давайте отсортируем массив ниже, используя сортировку Шелла.

Работа алгоритма сортировки Шелла

Шаг 1) Размер массива равен 8, поэтому начальное значение интервала равно h = 8/2 = 4.

Шаг 2) Группируйте элементы на расстоянии че��ырех позиций друг от друга. Подсписки: {8, 1}, {6, 4}, {7, 5}, {2, 3}.

Работа алгоритма сортировки Шелла

Шаг 3) Отсортируйте каждый подсписок с помощью сортировки вставками. Временная переменная хранит значение, которое помещается в список, пока элементы перемещаются. После перестановок массив будет выглядеть следующим образом.

Работа алгоритма сортировки Шелла

Шаг 4) Уменьшите интервал. Новый интервал равен h = 4/2 = 2.

Шаг 5) Поскольку 2 > 0, вернитесь к шагу 2 и сгруппируйте элементы на расстоянии двух позиций друг от друга: {1, 5, 8, 7} и {4, 2, 6, 3}.

Работа алгоритма сортировки Шелла

Отсортируйте первый подсписок. Массив примет следующий вид:

Работа алгоритма сортировки Шелла

После сортировки второго подсписка:

Работа алгоритма сортировки Шелла

Уменьшите интервал еще раз до h = 2/2 = 1. С интервалом в один символ сортировка Шелла выполняет заключительный проход сортировки вставками по всему массиву, как показано ниже.

Работа алгоритма сортировки Шелла

Работа алгоритма сортировки Шелла

Работа алгоритма сортировки Шелла

Шаг 6) Повторное деление интервала дает 0. Теперь массив полностью отсортирован:

Работа алгоритма сортировки Шелла

псевдо-Code для сортировки Shell

Start
Input array a of size n
for (interval = n / 2; interval > 0; interval /= 2)
    for (i = interval; i < n; i += 1)
        temp = a[i];
        for (j = i; j >= interval && a[j - interval] > temp; j -= interval)
            a[j] = a[j - interval];
        a[j] = temp;
End

Программа сортировки Шелла на C/C++

Входной сигнал:

//Shell Sort Program in C/C++
#include <bits/stdc++.h>
using namespace std;
void ShellSort(int data[], int size) {
    for (int interval = size / 2; interval > 0; interval /= 2) {
        for (int i = interval; i < size; i += 1) {
            int temp = data[i];
            int j;
            for (j = i; j >= interval && data[j - interval] > temp; j -= interval) {
                data[j] = data[j - interval];
            }
            data[j] = temp;
        }
    }
}
int main() {
    int data[] = {8, 6, 7, 2, 1, 4, 5, 3};
    int size = sizeof(data) / sizeof(data[0]);
    ShellSort(data, size);
    cout << "Sorted Output: \n";
    for (int i = 0; i < size; i++)
        cout << data[i] << " ";
    cout << "\n";
}

Выход:

Sorted Output:

1 2 3 4 5 6 7 8

Пример сортировки Шелла в Python

Входной сигнал:

#Shell Sort Example in Python
def ShellSort(data, size):
    interval = size // 2
    while interval > 0:
        for i in range(interval, size):
            temp = data[i]
            j = i
            while j >= interval and data[j - interval] > temp:
                data[j] = data[j - interval]
                j -= interval
            data[j] = temp
        interval //= 2
data = [8, 6, 7, 2, 1, 4, 5, 3]
ShellSort(data, len(data))
print('Sorted Output:')
print(data)

Выход:

Sorted Output:
[1, 2, 3, 4, 5, 6, 7, 8]

Применение сортировки Шелла

Сортировка Шелла по-прежнему используется в современных системах, где важны объем стека или простота.

  • ядро Linux Используется алгоритм сортировки Шелла в тех случаях, когда важно избежать стека вызовов.
  • Встроенная библиотека C uClibc использует алгоритм сортировки Shell для снижения потребления памяти.
  • В bzip2 используется сортировка Шелла, чтобы избежать глубокой рекурсии во время блочной сортировки.
  • Встроенное программное обеспечение отдает предпочтение сортировке Шелла для небольших наборов данных, где рекурсия ограничена.

Преимущества и недостатки сортировки Shell

Преимущества Недостатки
Для работы системы не требуется стек вызовов, что идеально подходит для встраиваемых систем. Не самый быстрый вариант для очень больших массивов.
Легко реализовать с помощью небольшого количества кода. Производительность снижается при обработке данных с широко разбросанными элементами.
Эффективен для массивов среднего размера или частично отсортированных массивов. Наихудшая временная сложность зависит от выбранной последовательности пауз.
Работает на месте, поэтому использует постоянную вспомогательную память. Это нестабильная сортировка, поэтому одинаковые ключи могут менять относительный порядок.

Анализ сложности сортировки Шелла

Временная сложность сортировки Шелла

Временная сложность алгоритма сортировки Шелла зависит от используемой последовательности пропусков.

В лучшем случае, когда массив уже почти упорядочен, каждый проход требует лишь логарифмического числа проверок, что дает O(n log n).

В худшем случае массив устроен таким образом, что элементам требуется максимальное количество сравнений, и в итоге приращение становится более сложным (O(n^2)) при использовании исходной последовательности Шелла.

  1. сложность в лучшем случае: O(n log n)
  2. Средняя сложность: от O(n log n) до O(n^(4/3)) в зависимости от последовательности пропусков.
  3. Наихудшая сложность: O(n^2) с исходной последовательностью Шелла.

Вопрос о том, какая последовательность пропусков является оптимальной для общего использования, остается открытым, хотя последовательности Седжвика и Чиуры хорошо зарекомендовали себя на практике.

Пространственная сложность сортировки Шелла

Сортировка Шелла не требует вспомогательных массивов, поэтому пространственная сложность составляет O(1) независимо от размера входных данных, что является одним из ее наиболее сильных практических преимуществ.

Часто задаваемые вопросы (FAQ)

Сортировка Шелла — это алгоритм сортировки с помощью сравнения на месте, предложенный Дональдом Шеллом в 1959 году. Он обобщает сортировку вставками, сравнивая элементы, находящиеся на значительном расстоянии друг от друга, а затем уменьшая это расстояние до тех пор, пока соседние элементы не будут отсортированы, что значительно сокращает количество перестановок.

Наилучшая временная сложность составляет O(n log n), а наихудшая — O(n^2) для исходной последовательности Шелла. Более совершенные последовательности с промежутками, такие как последовательность Седжвика, уменьшают наихудшую сложность примерно до O(n^(4/3)). Пространственная сложность составляет O(1).

Нет, сортировка Шелла нестабильна. Поскольку элементы сравниваются и меняются местами через большие промежутки, два одинаковых ключа могут изменить свой относительный порядок во время прохода. Если стабильность имеет значение, используйте сортировку слиянием или стабильный вариант сортировки вставками.

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

Искусственный интеллект-ассистенты могут проанализировать размер, распределение и ограничения вашего набора данных, а затем порекомендовать алгоритм, такой как сортировка Шелла, быстрая сортировка или поразрядная сортировка. Они также могут генерировать тестовые скрипты, сравнивающие время выполнения и использование памяти, чтобы вы могли проверить рекомендации на реальных рабочих нагрузках.

Да. Инструменты искусственного интеллекта могут создавать анимированные визуализации сортировки Шелла, которые в реальном времени выделяют группы пробелов, сравнения и перестановки. Такие визуализации помогают обучающимся увидеть, как уменьшается интервал и как массив сходится к отсортированному состоянию шаг за шагом.

Подведем итог этой публикации следующим образом: