52841.fb2 Я готуюсь до курсу інформатики. Алгоритмізація та програмування - читать онлайн бесплатно полную версию книги . Страница 27

Я готуюсь до курсу інформатики. Алгоритмізація та програмування - читать онлайн бесплатно полную версию книги . Страница 27

УРОК 26. Впорядкування таблиць

Мета уроку: Дати поняття про методи впорядкування табличних величин. Навчити розв’язувати задачі, що потребують сортування.

Теоретичний матеріал

Дуже часто при розв’язуванні задач, пов’язаних з обробкою масивів, необхідно виконувати сортування його елементів за зростанням або спаданням. Такі задачі мають велике практичне значення. Розглянемо деякі з методів, що дають змогу впорядкувати елементи таблиць.

Всі існуючі методи сортування можна поділити на три групи:

• обмінні сортування — виконується обмін між двома (найчастішесусідніми) елементами масивів, якщо відповідні елементи розташовані увихідному масиві невпорядковано; процес повторюється або певну кількість разів, або доки елементи в масиві не стануть впорядкованими;

• методи прямого вибору — в масиві обирається елемент з певнимивластивостями (наприклад, мінімум або максимум), а потім вибранийелемент ставиться на своє місце;

• методи прямої вставки — послідовно вибираються елементи з масивуі після визначення їх місця у впорядкованому наборі даних вставляютьсябезпосередньо на своє місце.

Найбільш відомим обмінним сортуванням є метод «бульбашки».

В ньому при послідовному проході по масиву порівнюються два сусідніх елементи. Якщо їх розміщення є неправильним (наприклад, при впорядкуванні за зростанням лівий елемент більший за правий), виконується взаємообмін елементів. Процес повторюється щонайменше N-1 разів, де N— кількість елементів у масиві.

Найпростіший алгоритм «бульбашки» має наступний вигляд:

Program Bubble; {Сортування за зростанням}

Const N=20;

Var Mas:array[1..N] of integer;

i,j:integer; {i,j — змінні циклу)

Rez: integer; {Rez — додаткова змінна для обміну елементів масиву між собою)

Begin

For i:=1 to N do

For j:=1 to N-l do

If Mas[j]>Mas[j+l] then

Begin

{Обмін елементів масиву через третю змінну)

Rez:=Mas[j]; Mas[j]:=Mas[j+1]; Mas[j+1]:=Rez;

End;

End.

Метод можна модифікувати, зменшуючи діапазон сортування після кожного проходу, адже ясно, що після кожного проходу максимальний елемент масиву буде «спливати наверх», тобто займати спочатку останню позицію таблиці, потім передостанню і так далі:

Програма, що реалізує описаний алгоритм має наступний вигляд:

Program Bubble; {Сортування за зростанням)

Const N=20

Var Mas:агay[1..N] of integer;

і,j:integer; {i,j — змінні циклу)

Rez:integer; {Rez - додаткова змінна для обміну елементів масиву між собою)

Begin

For i:=1 to N do

For j:=1 to N-i do

If Mas[j]>Mas[j+l] then

Begin

{Обмін елементів масиву через третю змінну}

Rez:=Mas[j]; Mas[j]:=Mas[j+1]; Mas[j+1]:=Rez;

End;

End.

Зверніть увагу, що в цьому алгоритмі у вкладеному циклі, що безпосередньо здійснює порівняння елементів, змінна циклу змінюється за іншим законом, ніж у попередньому випадку: від 1 до N-i, де і — змінна циклу зовнішньої команди повторення.

Другий метод модифікації алгоритму «бульбашки» полягає в тому, що ми вводимо додаткову змінну булівського типу (так званий прапорець), яка фіксуватиме при черговому проході була здійснена хоча б одна перестановка елементів чи ні. Адже очевидно, що якщо при черговому проході не відбулося жодної перестановки, то масив уже відсортований і процес перегляду можна припинити. Домовимось вважати прапорець «опущеним» (тобто рівним значенню false), якщо перестановки не відбулося, і «піднятим» (рівним true) — у протилежному випадку. Крім того, як і в попередньому випадку, після кожного проходу по масиву найбільший елемент «спливає» угору, тобто займає своє позицію. Тому вводимо додаткову змінну к, що фіксує праву границю впорядкованості, тобто при першому проході к = 1 і ми впорядковуємо всі елементи від 1 до N-1, на другому проході к = 2 і будуть впорядковуватись усі елементи від 1 до N- 2 (останній елемент уже впорядкований) і так далі. Програма має вигляд:

Program Bubble; {Сортування за зростанням}

Const N=20;

Var Mas:array[1..N] of integer;

i,j,k:integer; {i,j — змінні циклу, k — змінна, що фіксує праву границю впорядкування}

Rez:integer; {Rez — додаткова змінна для обміну елементів масиву між собою}

Flag:Boolean; {Flag — змінна, що фіксує, відбулася перестановка чи ні}

Begin

k:=1;

Repeat

Flag:=false; {Робимо припущення, що масив відсортований, а потім перевіряємо, чи правильним було це припущення, тобто чи немає серед елементів таких, що неправильно розташовані, якщо такі елементи будуть, то ми їх переставляємо і Flag присвоюємо значення true}

For і:=1 to N-k do

If Mas[i]>Mas[i+1]

then

begin

{Обмін елементів масиву через третю змінну}

Rez:=Mas[i];

Mas[і]:=Mas[i+1];

Mas[i+1]:=Rez;

Flag:=true;

End;

k:=k-1;

Until Flag = false;

End.

Другим методом сортування є метод прямого вибору. Один з його різновидів полягає в тому, що вибирається мінімальний елемент масиву, а потім виконується його обмін з першим елементом таблиці. Після цього перший елемент вважається впорядкованим і процес повторюється для підмасиву, що містить на один елемент менше за початковий, тобто елементи з 2-го до останнього. Процес повторюється кожен раз для масиву, зменшеного на один елемент. Закінчується він тоді, коли невпорядкований підмасив стає довжиною в один елемент. Таким чином, загальна кількість повторень дорівнює, як і в попередньому випадку, N-1 (N— кількість елементів масиву). Програма методу наведена нижче:

Program Selection;

Const N=20;

Var Mas:array[1..N] of integer;

і,j, Min,N_Min:integer;

Begin

For i:=1 to N-1 do

Begin

Min:=Mas[x]; {Зберігання еталону мінімуму}

N_Min:=i; {Зберігання номера мінімуму}

For j:=i+l to N do

If Mas[j]<Min

then begin

Min:=Mas[j]; {Перевизначекня еталону}

N_Min:=j; {Зберігання номеру еталону}

end;

{Обмін місцями мінімуму та першого елементу підмасиву}

Mas[N_Min]:=Mas[i];

Mas[i]:=Min;

End;

End.

Зверніть увагу, що пошук мінімуму в програмі організований стандартно, тобто перший елемент береться за еталон, а потім порівнюється з усіма останніми і, якщо новий елемент виявляється меншим за еталон, то еталон переприсвоюється. Крім цього, в алгоритмі запам’ятовується місце знаходження цього мінімального елемента для того, щоб після виходу з циклу можна було обміняти місцями знайдений мінімум і перший елемент підмасиву. Але оскільки підмасив увесь час змінює свій розмір, за еталон береться перший елемент саме того підмасиву, який розглядається на наступному кроці, тобто г’-ий елемент початкового масиву — змінна зовнішнього циклу, що вказує на початок нового підмасиву на кожному кроці).

Метод прямої вставки забезпечує вставку кожного елементу невпоряд-кованого масиву на своє місце у вже впорядкований масив. Один з методів такого сортування полягає в наступному. На початку сортування масив розбивається на два підмасиви, лівий з яких повинен бути впорядкованим, а правий — ні. У невідомому масиві тільки один елемент можна вважати впорядкованим, тому спочатку ліва відсортована частина складається всього з одного елементу. Потім по черзі беруться елементи з другої невпорядкованої частини і для них знаходиться місце вставки в першу частину таке, щоб впорядкованість не порушувалась. Це означає, що при сортуванні за зростанням необхідно знайти таке місце в масиві, де лівий елемент буде меншим або рівним тому, що вставляється, а правий — більшим за той, що вставляється. Після цього в масиві необхідно зробити зсув елементів, щоб звільнити місце, на яке і вставити черговий елемент.

Щоб оптимізувати розглянутий алгоритм, можна поєднати зсув елементів з пошуком місця вставляння. Для цього перевірки виконуються в зворотному напрямку від елемента, що потрібно вставити до місця вставки (тобто справа наліво). Оскільки елемент, що вставляється, береться першим з невпорядкованої частини масиву, то ліворуч від нього всі елементи вже впорядковані. Тому фактично необхідно порівнювати даний елемент з усіма лівішими від нього і, якщо даний елемент менший за той, з яким порівнюється, то виконується обмін елементів. Елемент наче «пливе» ліворуч від свого початкового місця розташування, і процес цей припиняється, якщо знайдений елемент не більший за даний або ми досягай початку масиву. Наприклад, даний такий масив:

12 -8 0 30 5 100

Розбиваємо його на дві частини. До першої входить єдиний впорядкований елемент {12}, а до другої—всі останні {-80305100}. Запишемо тепер процес впорядкування по етапах:

І етап: елемент, що впорядковується = - 8.

1) - 8 < 12, тому виконується обмін, тобто після першого кроку масив має вигляд:

-8 12 0 30 5 100

На цьому цикл припиняє свою роботу, тому що досягнуто початку масиву (і= 1).

IIетап: елемент, що впорядковується = 0.

1) 0 < 12, значить виконується обмін, тобто після першого кроку масивмає вигляд:

-8 0 12 30 5 100

2) 0 > - 8, значить обмін не виконується, здійснюється вихід із циклу,масив залишається без змін.

III етап: елемент, що впорядковується = 30.

1) 30 > 12, вхід до циклу не відбувається, масив залишається без змін.

IVетап: елемент, що впорядковується = 5.

1) 5 < 30, виконується обмін, після перестановки масив має вигляд:

-8 0 12 5 30 100

2) 5 < 12, здійснюється обмін, масив набуває вигляду:

-8 0 5 12 30 100

3) 5 > 0, цикл припиняє свою роботу, масив залишається без змін.

V етап: елемент, що впорядковується = 100.

1) 100 < 30, вхід до циклу не відбувається, тому що умова відразу хибна і масив залишається без змін. Програму наведено нижче:

Program Insert;

Const N=20;

Var Mas:array[1..N] of integer;

і,j,Rez:integer;

Begin

For i:=2 to N do

Begin

j:=i; {Цикл працює, доки лівий елемент більший за правий та доки не досягнуто початох масиву}

while (j>1) and (Mas[j]<Mas[j-1]) do

Begin

Rez:=Mas[j]; Mas[j]:=Mas[j-1]; Mas[j-1]:=Rez; j:=j-1;

End;

End;

End.

Домашнє завдання:

• Створити блок-схему запропонованих алгоритмів сортування («бульбашка» — 1-й та 2-й методи, метод прямого вибору, метод прямої вставки).