Алгоритм цифрового сортування RadixSort колись застосо-вувався у машинах для сортування перфокарт. В обчислюваль-них машинах першого покоління перфокарти, картонні карткй використовувалися для збереження інформації. На них за до-
199
помогою пристроїв, які називалися перфораторами, пробивали-ся дірки. На перфокарта у 80 колонках у певних позиціях можна було пробити до 12 дірок. Комбінації цих пробитих дірок від-повідали певному символу, тобто на кожній перфокарті можна було набити інформацію з 80 символів. Цифри від 0 до 9 кодува-лися дірками у відповідних рядках 0-9 у колонках, що відпові-дали даній цифрі (див. с. 50).
Сортувальні машини за вказаним стовпчиком, по якому не-обхідно було виконати сортування перфокарт, розкладали колоду перфокарт на 10 стосів залежно від того, яка з дірок 0-9 була пробита у вказаному стовпчику.
Ця ідея і лягла в основу алгоритму цифрового сортування масиву. Сформулюемо Е£.
Нехай задано масив цілих чисел, максимальна розрядність яких дорівнює d. Для прикладу розглянемо масив із 7 цілих трицифрових чисел:
329, 457, 657, 839, 436, 720, 355.
Розглянемо спочатку молодші розряди кожного елемента масиву. Там можуть бути цифри від 0 до 9. Розкладемо всі числа на 10 стосів: у перший - числа, які мають молодшу цифру 0, у другий - 1, у третій - 2, і т. д., у десятий - 9 (мал. 85).
|
720 |
|
|
|
|
355 |
436 |
657 457 |
|
839 329 |
0123456789
Мал. 85
Тепер складемо стоси чисел знову разом, зберігаючи первин-ну послідовність чисел у кожному стосі відносно їх ПОСЛІДОВ-ності в заданому масиві:
720, 355, 436, 457, 657, 329, 839.
На другому кроці сортування будемо цей масив розкладати на стоси відповідно до цифр десятків кожного числа (мал. 86).
|
|
|
329 720 |
839 43G |
|
657 457 355 |
|
|
|
|
о
8
12 3 4 5 6 7
Мал. 86
Склавши отримані числа зі стосів один за одним, отримаємо: 720, 329, 436, 839, 355, 457, 657. 200
Залишився один останній крок для розкладання чисел по стосах відповідно до старших розрядів, тобто цифр сотень кожного числа (мал. 87).
|
|
|
|
355 329 |
457 436 |
|
657 |
720 |
839 |
|
0123456789
Мал. 87
Запишемо числа, отримані у стосах, зберігаючи їх порядок у масиві, з якого вони потрапили у ці стоси. Результатом буде відсортований масив чисел:
329, 355, 436, 457, 657, 720, 839.
За три кроки отримали результат роботи алгоритму цифрового сортування. Чому саме за три? Зрозуміло - це прямо по-в'язано з кількістю цифр у найбільшому числі. До оцінки ефек-тивності роботи даного алгоритму звернемося пізніше.
А зараз давайте спробуємо записати алгоритм цифрового сортування:
1) зарезервуватимісце для 10 додаткових масивівAg, Av ...,Ад (довжина їх повинна збігатися з довжиною вхідного масиву, оскільки можна підібрати такий тест, щоб усі елементи вхід- ного масиву попали в один стос);
2) визначити розрядність найбільшого числа вхідного масиву; 3)визначити і = 1;
виділити в кожному числі заданого масиву і-у цифру і пе-реписати всі числа, починаючи з першого і завершуючи остан-нім, у додатковии масив, порядковии номер якого збігається з і-ю цифрою поточного числа;
переписати числа з масивів А0, А., ..., А9 у вхідний масив, зберігаючи їх послідовність у додаткових масивах;
збільшити і на 1 і якщо і не перевищує розрядності най-більшого числа, то перейти до пункту 4.
А тепер запишемо алгоритм цифрового сортування елемен-тів одновимірного масиву у вигляді тексту фрагмента Pascal-програми. Для спрощення вважатимемо, що значениями еле-ментів масиву є натуральні числа.
(Пошук максимального елемента вхідного масиву.} read (х[1]); max :=х[1]; for i := 2 to n do begin
read (x[i]);
if x[i] > max then max :=x[i]; end;
201
d := 0; {Визначення розрядності максимального числа.)
while max > 0 do begin inc (d);
max := maxdiv 10 end; count := 1;
for i := 1 to d do {Порозрядний перегляд елементів масиву.}
begin
{Ініціалізація кількості елементів у масивахЛ0, ...,Ад.) forj :=0to9dok[j] :=0;
for j : = 1 to n do {Розміщення елементів масиву x по масивам А0,.... А9.) begin
digit := (x[j] div count) mod 10; inc (k[digit]); A[digit][k[digit]]:=x[j] end; count := count * 10; {Визначення наступного розряду елементів масиву.} j := 1; {Злиття елементів з масивів А0, ...,/19у масивх.}
for q := 0 to 9 do forw:= 1 to k[q] do begin
x[j]:=A[q][w]; inc(j) end; end;
Перейдемо до визначення оцінки ефективності роботи алгоритму цифрового сортування елементів масиву. її можна об-рахувати, проаналізувавши наведений текст програми. Та частина програми, яка безпосередньо виконує сортування масиву, складається з двох вкладених циклів: перший for і := 1 to d do залежить від кількості знаків найбільшого числа заданого масиву, а другий for j := 1 to n do - від кількості елементів цього масиву. Усередині зовнішнього циклу є где один цикл for q := 0 to 9 do, який збирає елементи, розкладені по стосам, в один масив. Він загалом переглядає п елементів заданого масиву. Тому результатом такого аналізу перегляду п елементів масиву буде d(n + п) - 2dn. Оскільки величина d є значно малою порівняно з п (maxlongint = 2147483647), то оцінкою ефективності роботи алгоритму цифрового сортування можна вважати 0(п).
Цифрове сортування досить чутливе до кількості вхідних даних. Тому при тестуванні цього алгоритму необхідно вра-хувати саме цей фактор. Але традиційно коректність його роботи перевірятимемо при п > 100 на таких вхідних даних:
вхідний масив уже впорядкований необхідним чином;
вхідний масив є частково впорядкованим;
202
вхідний масив упорядкований у зворотному порядку;
елементи вхідного масиву розміщені випадковим чином.
/ Запитання для самоконтролю
Якою є історія застосування алгоритму цифрового сортуванкя?
У чому полягає ідея алгоритму цифрового сортування?
Продемонструйте на власному прикладі роботу алгоритму цифрового сортування.
Сформулюйте алгоритм цифрового сортування у словесній формі.
Запишіть текст Pascal-програми, що реалізує алгоритм цифрового сортування одновимірного масиву.
Проаналізуйте переваги й обмеження щодо використання методу цифрового сортування.
Якою є оцінка ефективності роботи алгоритму, що реалізує метод цифрового сортування одновимірного масиву? Обґрунтуйте свою відповідь.
Завдання
Реалізувати у вигляді прогреми алгоритм цифрового сортування заданої послідовності за зростанням.
Модифікувати алгоритм, реалізований у завданні 1, так, гцоб сортування відбувалося за спаданиям.
Протестувати реалізовані у завданнях 1-2 алгоритми для масиву 15, 4, 10, 8, 6, 9, 16, 1, 7, 3, 11, 14, 2, 5, 12, 13.
Проаналізувати покрокове виконання завдання 3 щодо кількості виконуваних дій.
Шдібрати власні тести, які доводить переваги й показу-ють недоліки методу цифрового сортування при п > 100.
Зробити письмовий аналіз завдань 3-5.
ПОРІВНЯННЯ МЕТОДІВ СОРТУВАННЯ
Завершуючи ознайомлення з різноманітними та різноплано-вими методами сортування, на останок спробуємо порівняти їх ефективність. Традиційно вважатимемо п кількістю елементів масиву, що сортується.
Для того щоб порівняння алгоритмів, що реалізують відпо-відні методи сортування, було достатньо наочним, заноситиме-мо час їх виконання в таблицю з параметрами, які визначають таке початкове формування елементів вхідного масиву: упорядкований за зростанням Growth, визначений випадковим чином Random, упорядкований за спаданиям Decrease. Нага-дуемо, що робота всіх алгоритмів сортування спрямована на сортування вхідних масивів за зростанням.
203
Оскільки замір часу виконання алгоритмів залежить не лише від кількості елементів масивів, а й від технічних характеристик комп'ютера, на якому вони тестувалися, то зазначи-мо, що тестування відбувалося на комп'ютері AMD Duron, 1.00 ГТц, 128 МБ ОЗУ. Вибір саме такого комп'ютера спри-чинено тим, що на потужніших комп'ютерах досить важко за-фіксувати час виконання програм, що реалізують «швидкі» алгоритми, особливо ті, які певним чином обмежують кіль-кість оброблювальних елементів (наприклад, сортування за лі-нійний час). I навпаки, на «повільніших» машинах ыеможливо дочекатися результату роботи програм, що реалізують прямі методи сортування.
Як уже зазначалося, для фіксації часу роботи програми, що реалізує розроблений алгоритм, можна застосувати таку змінну:
var timer: longint absolute $40: $6c.
Зазначимо також (див. с. 23), що під час тестування програм фіксувався «чистий» час їх роботи, тобто не враховувалося введения вхідної інформації та виведення результуючого відсорто-ваного масиву. Тобто загальний вигляд програми був таким:
timeold := timer;
<програма>
writeln ((timer - timeold) /18. 2);
Під час тестування виявилося, що на обраному комп'ютері не для всіх тестів і не для всіх алгоритмів вдалося зафіксувати час. При такій ситуації в таблицю заносився коментар «no time». I ще: для спрощення замість log2n будемо вказувати logn.
Шсля обговорення всіх технічних питань перейдемо безпосе-редньо до проведения порівняння методів сортування (табл. 19).
Таблица 19
|
Тип методу |
Назва методу |
Оцінка |
Тип |
Growth |
Random |
Decrease |
|
N = 1000 |
||||||
|
Прямі методи |
Вибором |
п- |
word |
no time |
no time |
no time |
|
Обміном |
пг |
word |
no time |
0,055 |
0,055 |
|
|
Включениям |
п1- |
word |
no time |
no time |
0,055 |
|
|
о Si ф |
Бінарне включения |
пг |
word |
no time |
no time |
no time |
|
Шейкерие сортування |
пг |
word |
no time |
no time |
no time |
|
204
Продовження таблиці 19
|
Тип методу |
Назва методу |
Оцінка |
Тип |
Growth |
Random |
Decrease |
|
Удоско- налені методи |
Метод Шелла |
л log л |
word |
no time |
no time |
no time |
|
Пірамідальне сортування |
л log л |
word |
no time |
no time |
no time |
|
|
Швидке сортування |
л log л |
word |
no time |
no time |
no time |
|
|
Сортуван- НЯ ПОСЛІ- довностей |
Пряме злиття |
л [log л] |
word |
no time |
no time |
no time |
|
Природне злиття |
л [logл] |
word |
no time |
no time |
no time |
|
|
Лінійне сорту- вання |
Сортування підрахунком |
л |
word |
no time |
no time |
no time |
|
Цифрове сортування |
л |
word |
no time |
no time |
no time |
|
|
N = 5000 |
||||||
|
Прямі методи |
Вибором |
пг |
word |
0,1648 |
0,1648 |
0,2198 |
|
Обміном |
п* |
word |
0,275 |
0,495 |
0,659 |
|
|
Включениям |
п2 |
word |
no time |
0,1648 |
0,385 |
|
|
hi |
Бінарне включения |
л2 |
word |
no time |
0,1099 |
0,275 |
|
Шейкерне сортування |
л2 |
word |
no time |
0,44 |
0,66 |
|
|
Удоско- валені методи |
Метод Шелла |
n]ogn |
word |
no time |
no time |
no time |
|
Пірамідальне сортування |
л log л |
word |
no time |
no time |
no time |
|
|
Швидке сортування |
nlogn |
word |
no time |
no time |
no time |
|
|
Сортуван- НЯ ПОСЛ1- довностей |
Пряме злиття |
л [logл] |
word |
no time |
no time |
no time |
|
Природне злиття |
л [log л] |
byte |
no time |
no time |
no time |
|
|
щ |
Сортування підрахунком |
л |
word |
no time |
no time |
no time |
|
Цифрове сортування |
я |
word |
no time |
no time |
no time |
|
|
N=10 000 |
||||||
|
Прямі методи |
Вибором |
л2 |
word |
0,659 |
0,659 |
0,879 |
|
Обміном |
л2 |
word |
1,044 |
2,088 |
2,582 |
|
|
Включениям |
л2 |
word |
no time |
0,714 |
1,538 |
|
205
Продовжепня таблиці 19
|
Тип методу |
Назва методу |
Оцінка |
Тип |
Growth |
Random |
Decrease |
|
Покрещен! методи |
Бінарне включения |
л2 |
word |
no time |
0,055 |
1,099 |
|
Шейкерне сортування |
л2 |
word |
по time |
1,648 |
2,692 |
|
|
Удоско- налені методи |
Метод Шелла |
nlogn |
word |
по time |
по time |
по time |
|
Шрамідальне сортування |
л log л |
word |
по time |
по time |
по time |
|
|
Швидке сортування |
nlogn |
word |
по time |
по time |
по time |
|
|
Сортуван- НЯ ПОСЛІ- довностей |
Пряме злиття |
n[\ogn] |
word |
по time |
по time |
по time |
|
Природне злиття |
n[\ogn] |
byte |
по time |
0,165 |
по time |
|
|
Лінійне сорту- вання |
Сортування підрахунком |
n |
word |
по time |
по time |
по time |
|
Цифрове сортування |
n |
word |
по time |
по time |
по time |
|
|
JV=15 000 |
||||||
|
Прямі методи |
Вибором |
л2 |
word |
1,484 |
1,484 |
1,978 |
|
Обміном |
n1 |
word |
2,418 |
4,78 |
5,934 |
|
|
Включениям |
n- |
word |
по time |
1,648 |
3,352 |
|
|
Покра- щені методи |
Бінарне включения |
n2 |
word |
по time |
1,209 |
2,418 |
|
Шейкерне сортування |
n2 |
word |
по time |
3,736 |
5,989 |
|
|
Удоско- налені методи |
Метод Шелла |
nlogn |
word |
по time |
по time |
по time |
|
Пірамідальне сортування |
nlogn |
word |
по time |
по time |
по time |
|
|
Швидке сортування |
nlogn |
word |
по time |
по time |
по time |
|
|
Сортуван-ня ПОСЛІ-довностей |
Пряме злиття |
л [logл] |
word |
по time |
по time |
по time |
|
Природне злиття |
л [log я] |
Масив не можна визначити |
||||
|
Лівійне сорту- вання |
Сортування підрахунком |
л |
word |
по time |
по time |
по time |
|
Цифрове сортування |
л |
Масив не можна визначити |
||||