Коллекция алгоритмов

Корневая сортировка
    При корневой сортировке упорядочивание списка происходит без непосредственного сравнения ключевых значений между собой. При этом создается набор "стопок", а элементы распределяются по стопкам в зависимости от значений ключей. Собрав значения обратно и повторив всю процедуру для последовательных частей ключа, мы получаем отсортированный список. Чтобы такая процедура работала, распределение по стопкам и последующую сборку следует выполнять очень аккуратно.
    Подобная процедура используется при ручной сортировке карт. В некоторых библиотеках в докомпьютерные времена при выдаче книги заполнялась карта выдачи. Карты выдачи были занумерованы, а сбоку на них проделывался ряд выемок - в зависимости от номера карты. При возвращении книги карта выдачи удалялась, и ее клали в стопку. Затем вся стопка прокалывалась длинной иглой на месте первой выемки, и иглу поднимали. Карты с удаленной выемкой оставались на столе, а остальные были наколоты на иглу. Затем две получившиеся стопки переставлялись так, что карточки на игле шли за карточками с отверстиями. Затем игла втыкалась в месте выемки и весь процесс повторялся. После прокалывания по всем позициям карты оказывались в порядке возрастания номеров.
    Эта процедура ручной обработки разделяет карты по значению младшего разряда номера на первом шаге и старшего разряда на последнем. Компьютеризированные вариант этого алгоритма использует 10 стопок:
RadixSort(list, N)	
list			сортируемый список элементов
N				число элементов в списке

shift  = 1
for loop = 1 to keySize do
	for entry = 1 to N do
		bucketNumber = (list[entry].key / shift) mod 10
		Append(bucket[bucketNumber], list[entry])
	end for entry
	list = CombineBuckets()
	shift = shift*10
end for loop		
			  
    Начнем с обсуждения этого алгоритма. При вычислении значения переменной bucketNumber из ключа вытаскивается одна цифра. При делении на shift ключевое значение сдвигается на несколько позиций вправо, а последующее применение операции mod оставляет лишь цифру единиц полученного числа. При первом проходе с величиной сдвига 1 деление не меняет числа, а результатом операции mod служит цифра единиц ключа. При втором проходе значение переменной shift будет уже равно 10, поэтому целочисленное деление и последующее применение операции mod дают цифру десятков. При очередном проходе будет получена следующая цифра числа.
    Функция CombineBuckets вновь сводит все стопки от bucket[0] до bucket[9] в один список. Этот переформированный список служит основой для следующего прохода. Поскольку переформирование стопок идет в определенном порядке, а числа добавляются к концу каждой стопки, ключевые значения постепенно оказываются отсортированными.

Исходный список:
310 213 023 130 013 301 222 032 201 111 323 002 330 102 231 120

Номер стопки
Содержимое
0
310
130
330
120
1
301
201
111
231
2
222
032
002
102
3
023
023
013
323
(а) Первый проход, разряд единиц

Список, полученный в результате первого прохода:
310 130 330 120 301 201 111 231 222 032 002 102 213 023 013 323

Номер стопки
Содержимое
0
301
201
002
102
1
310
111
213
013
2
120
222
023
323
3
130
330
231
032
(б) Второй проход, разряд десятков

Список, полученный в результате второго прохода:
301 201 002 102 310 111 213 013 120 222 023 323 130 330 231 032

Номер стопки
Содержимое
0
002
013
023
032
1
102
111
120
130
2
201
213
222
231
3
301
310
323
330
(в) Третий проход, разряд сотен

    Здесь показаны три прохода на списке трехзначных чисел. Для упрощения примера в ключах используются только цифры от 0 до 3, поэтому достаточно четырех стопок.
    При взгляде на (в) становится ясно, что если вновь собрать стопки по порядку, то получится отсортированный список.


Рейтинг@Mail.ru Rambler's Top100
Сайт управляется системой uCoz