Гномья сортировка массива на Ассемблере
Гномья сортировка массива на Ассемблере
Гномья сортировка - один из методов сортировки данных, сочетающий в себе элементы алгоритмов сортировки пузырьком и сортировки вставками. Такое необычное название алгоритм получил благодаря голландскому ученому Дику Груну, детально исследовавшему этот метод сортировки. Вот как он описывает гномью сортировку в своих работах:
Гномья сортировка основана на технике, используемой обычным голландским садовым гномом. Это метод, которым садовый гном сортирует линию цветочных горшков. Он смотрит на следующий и предыдущий садовые горшки: если они в правильном порядке, он шагает на один горшок вперед, иначе он меняет их местами и шагает на один горшок назад. Граничные условия: если нет предыдущего горшка, он шагает вперед; если нет следующего горшка, он закончил.
Алгоритм находит первое место, где два соседних элемента стоят в неправильном порядке и меняет их местами. Он пользуется тем фактом, что обмен может породить новую пару, стоящую в неправильном порядке, только до или после переставленных элементов. Сортировка простая, не требует вложенных циклов и вспомогательных массивов, все данные сортируются за один проход.
Благодаря своей простоте, алгоритм гномьей сортировки легко реализуется практически на любом языке программирования. Вот мой вариант функции сортировки на Ассемблере:
Code (Assembler) : Убрать нумерацию
- ;----------------------------------------------------------------
- ; Функция "гномьей сортировки" массива DWORD
- ; by ManHunter / PCL (www.manhunter.ru)
- ;----------------------------------------------------------------
- ; Параметры:
- ; lpArray - указатель на массив DWORD
- ; dLen - количество элементов в массиве
- ;----------------------------------------------------------------
- proc gnome_sort lpArray:DWORD, dLen:DWORD
- pusha
- ; В массиве меньше 2 элементов?
- cmp [dLen],2
- jb .loc_ret
- mov esi,[lpArray]
- xor ecx,ecx
- inc ecx
- .loc_loop:
- or ecx,ecx
- jz @f
- mov eax,[esi+ecx*4-4]
- mov ebx,[esi+ecx*4]
- cmp eax,ebx
- ; Для сортировки массива по убыванию замените
- ; условный переход JBE на JAE
- jbe @f
- ; Поменять местами соседние элементы
- mov [esi+ecx*4-4],ebx
- mov [esi+ecx*4],eax
- dec ecx
- jmp .loc_loop
- @@:
- inc ecx
- cmp ecx,[dLen]
- jb .loc_loop
- .loc_ret:
- popa
- ret
- endp
Сортировку можно заметно ускорить, если запоминать индекс крайнего неотсортированного элемента. После того как сделан ряд шагов назад, дальнейшую обработку массива необходимо продолжить с того места, где прервались. Я немного модифицировал предыдущую функцию, в результате получилась оптимизированная функция гномьей сортировки:
Code (Assembler) : Убрать нумерацию
- ;----------------------------------------------------------------
- ; Функция оптимизированной "гномьей сортировки" массива DWORD
- ; by ManHunter / PCL (www.manhunter.ru)
- ;----------------------------------------------------------------
- ; Параметры:
- ; lpArray - указатель на массив DWORD
- ; dLen - количество элементов в массиве
- ;----------------------------------------------------------------
- proc gnome_sort lpArray:DWORD, dLen:DWORD
- pusha
- ; В массиве меньше 2 элементов?
- cmp [dLen],2
- jb .loc_ret
- mov esi,[lpArray]
- xor ecx,ecx
- inc ecx
- mov edx,ecx
- .loc_loop:
- or ecx,ecx
- jz @f
- mov eax,[esi+ecx*4-4]
- mov ebx,[esi+ecx*4]
- cmp eax,ebx
- ; Для сортировки массива по убыванию замените
- ; условный переход JBE на JAE
- jbe @f
- ; Поменять местами соседние элементы
- mov [esi+ecx*4-4],ebx
- mov [esi+ecx*4],eax
- dec ecx
- jmp .loc_loop
- @@:
- ; Перейти на крайний неотсортированный элемент
- inc edx
- mov ecx,edx
- cmp edx,[dLen]
- jb .loc_loop
- .loc_ret:
- popa
- ret
- endp
Просмотров: 5449 | Комментариев: 7
Метки: Assembler, полезные функции
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
ManHunter
(31.03.2016 в 08:07):
uuu, садись, двойка.
http://asmworld.ru/uchebnyj-ku...eniya-metok/ , глава "Анонимные метки".
http://asmworld.ru/uchebnyj-ku...eniya-metok/ , глава "Анонимные метки".
uuu
(31.03.2016 в 00:06):
метка @f отсутствует, вместо нее @@
@@:
->
@f:
@@:
->
@f:
ManHunter
(23.03.2016 в 15:30):
Так гигабайты никто "в лоб" и не сортирует без особой надобности. Индексы, сортировка частями, деревья и прочие оптимизации, это же не просто так придумано.
Андрей
(23.03.2016 в 13:11):
Я не спорю, для общего круга задач это вполне приемлемо. Какой нибудь список там или базу данных упорядочить. Но если массив разрастается условно до гигабайта, то там сравнение каждого элемента уже роскошь. Время жрёт - караул!
Допустим всего десять неупорядоченных элементов это уже десять гиг сравнеий и передвижек.
Пардон. читать как "десять неупорядоченных элементов в конце списка это уже десять гиг сравнеий и передвижек."
Допустим всего десять неупорядоченных элементов это уже десять гиг сравнеий и передвижек.
Пардон. читать как "десять неупорядоченных элементов в конце списка это уже десять гиг сравнеий и передвижек."
ManHunter
(23.03.2016 в 12:36):
Сто тысяч рандомных DWORD'ов сортирует быстрее, чем за пару секунд. Десяток тысяч - вообще без видимой паузы. И это не на топовом железе.
Андрей
(23.03.2016 в 12:21):
Грусть - печаль такой сортировки в том что она хороша только для небольших массивов.
Добавить комментарий
Заполните форму для добавления комментария
https://fasmworld.ru/uchebnyj-...eniya-metok/