WikiSort.ru - Программирование

ПОИСК ПО САЙТУ | о проекте
Иллюстрация действия алгоритма гномьей сортировки

Гномья сортировка (англ. Gnome sort) — алгоритм сортировки, похожий на сортировку вставками, но в отличие от последней перед вставкой на нужное место происходит серия обменов, как в сортировке пузырьком. Название происходит от предполагаемого поведения садовых гномов при сортировке линии садовых горшков.

«Гномья сортировка основана на технике, используемой обычным голландским садовым гномом (нидерл. tuinkabouter). Это метод, которым садовый гном сортирует линию цветочных горшков. По существу он смотрит на текущий и предыдущий садовые горшки: если они в правильном порядке, он шагает на один горшок вперёд, иначе он меняет их местами и шагает на один горшок назад. Граничные условия: если нет предыдущего горшка, он шагает вперёд; если нет следующего горшка, он закончил.
Дик Грун
»

Алгоритм концептуально простой, не требует вложенных циклов. Время работы . На практике алгоритм может работать так же быстро, как и сортировка вставками.

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

Описание

Ниже написан псевдокод сортировки. Это оптимизированная версия с использованием переменной j, чтобы разрешить прыжок вперёд туда, где он остановился до движения влево, избегая лишних итераций и сравнений:


gnomeSort(a[0..size - 1])
    i = 1;
    j = 2;
    while i < size
        if a[i - 1] > a[i] //для сортировки по возрастанию поменяйте знак сравнения на <
            i = j;
            j = j + 1;
        else
            swap a[i - 1] and a[i]
            i = i - 1;
            if i == 0
                i = j;
                j = j + 1;

Пример:

Если мы хотим отсортировать массив с элементами [4] [2] [7] [3] от большего к меньшему, то на итерациях цикла while будет происходить следующее:

  • [4] [2] [7] [3] (начальное состояние: i == 1, j == 2);
  • [4] [2] [7] [3] (ничего не произошло, но сейчас i == 2, j == 3);
  • [4] [7] [2] [3] (обмен a[2] и a[1], сейчас i == 1, а j == 3 по-прежнему);
  • [7] [4] [2] [3] (обмен a[1] и a[0], сейчас i == 3, j == 4);
  • [7] [4] [3] [2] (обмен a[3] и a[2], сейчас i == 2, j == 4);
  • [7] [4] [3] [2] (ничего не произошло, но сейчас i == 4, j == 5);
  • цикл закончился, т. к. i не < 4.

Реализация на С++

template <class T>
void gnome_sort(T A[], std::size_t N) {
    for (std::size_t i = 0; i + 1 < N; ++i) {
        if (A[i] > A[i + 1]) {
            std::swap(A[i], A[i + 1]);
            if (i != 0)
                i -= 2; //вычитается два и потом прибавляется один
        }
    }
}

Реализация на Java

 1 void gnomeSort(int[] a) {
 2     int i = 1;
 3     while(i < a.length) {
 4         if(i == 0 || a[i - 1] <= a[i])
 5             i++;
 6         else {
 7             int temp = a[i];
 8             a[i] = a[i - 1];
 9             a[i - 1] = temp;
10             i--;
11         }
12     }
13 }

Реализация на Python

def gnome_sort(arr):
    i = 1
    while i < len(arr):
        if not i or arr[i - 1] <= arr[i]:
            i+=1
        else:
            arr[i], arr[i - 1] = arr[i - 1], arr[i]
            i-=1
    return arr

Оптимизация

В результате оптимизации гномья сортировка естественно трансформируется в сортировку вставками. Каждый раз «гном» наталкивается на новый номер, все значения слева от «гнома» уже отсортированы.

Ссылки


Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".

Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.

Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .




Текст в блоке "Читать" взят с сайта "Википедия" и доступен по лицензии Creative Commons Attribution-ShareAlike; в отдельных случаях могут действовать дополнительные условия.

Другой контент может иметь иную лицензию. Перед использованием материалов сайта WikiSort.ru внимательно изучите правила лицензирования конкретных элементов наполнения сайта.

2019-2024
WikiSort.ru - проект по пересортировке и дополнению контента Википедии