Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабораторна робота_9

.pdf
Скачиваний:
20
Добавлен:
17.03.2016
Размер:
414.71 Кб
Скачать

Лабораторна робота №9 Алгоритми сортування та пошуку

Мета роботи: ознайомитися з алгоритмами пошуку та сортування. Ознайомитися з покращеними алгоритмами сортування.

Завдання Проаналізувати варіант завдання. Скласти блок-схему алгоритму і у всіх завданнях потрібно написати, налагодити і протестувати програму, що забезпечує виконання наступних дій:

Введення розміру масиву (або двох - залежно від завдання) Введення початкового масиву (масивів)

Виведення введених масивів Обробка масиву (масивів) відповідно до варіанту Виведення одержаних масивів

Вивід індексу та значення шуканого елементу. Заданий елемент вводити з клавіатури.

Зауваження:

Масив заповнювати за допомогою генератора випадкових чисел. Кількість елементів у вихідних масивах до 20 штук. Елементами масивів є цілі числа.

Після кожної зміни масивів новий стан необхідно вивести на екран. «Скопіювати елементи» - елементи з вихідного масиву додаються в

результуючий масив.

«Перенести елементи» - елементи з вихідного масиву додаються в результуючий масив, після чого видаляються з початкового.

Пошук здійснювати методом бінарного пошуку.

Варіанти завдань:

1Ввести масив А. У масив В скопіювати всі елементи масиву А, що мають парний індекс і парне значення. Масив В впорядкувати за спаданням, використовуючи метод обміну.

2Ввести масив А. У масив В перенести всі елементи масиву А, що мають парний індекс і непарне значення. Масив В впорядкувати за зростанням, використовуючи метод простого вибору.

3Ввести масив А. У масив B скопіювати всі елементи масиву А, що мають парний індекс, ліворуч від яких розташовані елементи з непарним значенням. Масив В впорядкувати за зростанням, використовуючи метод вставками.

4Ввести масив А. У масив В перенести всі елементи масиву А, що мають парний індекс, праворуч від яких розташовані елементи з непарним значенням. Масив В впорядкувати за спаданням, використовуючи метод злиттям.

5Ввести масив А. У масив В перенести всі елементи масиву А, що мають непарний індекс, праворуч від яких розташовані елементи з непарним значенням, а ліворуч - з парним. Масив В впорядкувати за спаданням, використовуючи метод обміну.

6Ввести масив А. У масив В перенести всі елементи масиву А, що стоять

лівіше мінімального елемента і мають непарний індекс. Масив В впорядкувати за спаданням, використовуючи метод Шелла.

7Ввести масив А. У масив В перенести всі елементи масиву А, що стоять правіше максимального елемента і мають непарний індекс. Масив В впорядкувати за зростанням, використовуючи метод швидкого сортування.

8Ввести масив А. У масив В перенести всі елементи масиву А, що стоять між мінімальним і максимальним елементами. Масив В впорядкувати за зростанням, використовуючи метод сортування злиттям.

9Ввести масив А. У масив В перенести всі елементи масиву А, що мають значення більше ніж (min+max)/2, де min – значення мінімального елемента масиву, а max - значення максимального елемента масиву. Масив В впорядкувати за спаданням, використовуючи метод сортування метод простого вибору.

10Ввести масив А. У масив В перенести всі елементи масиву А, що мають значення менше ніж (min+max)/3, де min – значення мінімального елемента масиву, а max - значення максимального елемента масиву. Масив В впорядкувати за спаданням, використовуючи сортування методом вставок.

11Ввести масиви А і В. У масив С скопіювати ті елементи, які є і в масиві А, і в масиві В. З масиву В видалити всі парні елементи. Масиви А, В і С впорядкувати за зростанням використовуючи метод обміну.

12Ввести масиви А і В. У масив С скопіювати ті елементи, які є в масиві А, але яких немає в масиві В. З масиву А видалити всі непарні елементи. Масиви А, В і С впорядкувати за спаданням, використовуючи метод Шелла.

13Ввести масиви А і В. У масив С скопіювати ті елементи масиву А, яких немає в масиві В, і ті елементи масиву В, яких немає в масиві А. З масиву В видалити всі парні елементи. Масиви А, В і С впорядкувати за зростанням, використовуючи швидке сортування.

14Ввести масиви А і В. У масив С скопіювати ті елементи масиву А, яких немає в масиві В, і ті елементи масиву В, які зустрічаються в масиві А принаймні 2 рази. З масиву А видалити всі елементи, що стоять лівіше мінімального елемента. Масиви А, В і С впорядкувати за спаданням, використовуючи сортування методом злиття.

15Ввести масиви А і В. У масив С скопіювати ті елементи масиву А, які зустрічаються в масиві В принаймні 2 рази, і ті елементи масиву В, які зустрічаються в масиві А рівно 1 раз. З масиву А видалити всі елементи, які стоять лівіше максимального елемента. Масиви А, В і С впорядкувати за спаданням, використовуючи сортування методом вставками.

16Ввести масиви А і В. У масив С перенести ті елементи масиву А, які менші мінімального елемента масиву В, і ті елементи масиву В, які

більші максимального елемента масиву А. Масиви А, В і С

впорядкувати за зростанням, використовуючи сортування методом швидкого сортування.

17Ввести масиви А і В. У масив С перенести ті елементи масиву А, які більше мінімального елемента масиву В, і ті елементи масиву В, які більше максимального елемента масиву А. Масиви А, В і С впорядкувати за зростанням, використовуючи метод обміну.

18Ввести масиви А і В. У масив С перенести ті елементи масиву А, які більше максимального елемента масиву В, і ті елементи масиву В, які менше максимального елемента масиву А. Масиви А, В і С впорядкувати за спаданням, використовуючи метод простого вибору.

19Ввести масиви А і В. У масив С перенести парні елементи масиву А, і непарні елементи масиву В. Масиви А, В і С впорядкувати за спаданням, використовуючи сортування методом Шелла.

20Ввести масиви А і В. У масив С перенести ті парні елементи масиву А, лівіше яких стоять елементи з непарним значенням. Також в масив С перенести елементи масиву В, які за значенням ближче всіх до (min+max)/2, де min - значення мінімального елемента масиву В, max - значення максимального елемента масиву В. Масиви А, В і С впорядкувати за зростанням, використовуючи сортування методом злиття.

21Ввести масиви А і В. У масив С перенести ті елементи, що присутні в обох масивах А і В. Масиви А, В і С впорядкувати за зростанням, використовуючи сортування методом Хоара.

22Ввести масиви А і В. У масив С перенести ті елементи, що присутні в обох масивах А і В в одному екземплярі. Масиви А, В і С впорядкувати за зростанням, використовуючи сортування методом Шелла.

23Ввести масиви А і В. У масив С скопіювати ті елементи масиву А, яких немає в масиві В, і ті елементи масиву В, яких немає в масиві А. З масиву В видалити всі елементи кратні двом. Масиви А, В і С впорядкувати за зростанням, використовуючи сортування методом вставок.

24Ввести масив А. У масив В скопіювати всі елементи масиву А, що мають парний індекс і кратні двом. Масив В впорядкувати за спаданням, використовуючи метод обміну.

25Ввести масив А і В. У масив С перенести всі елементи масиву А, що мають парний індекс та елементи масиву В праворуч від яких розташовані елементи з непарним значенням. Масиви А, В і С впорядкувати за спаданням, використовуючи метод злиття.

26Ввести масиви А і В. У масив С скопіювати ті елементи масиву А, яких немає в масиві В. З масиву А видалити всі елементи кратні трьом. Масиви А, В і С впорядкувати за зростанням, використовуючи сортування методом вибору.

Контрольні запитання:

1.Що таке сортування масиву?

2.Поясніть алгоритм сортування масиву методом прямого вибору.

3.Поясніть алгоритм сортування масиву методом обміну.

4.Поясніть алгоритм сортування масиву методом вставок?

5.Поясніть пошук заданого елемента масиву лінійним методом.

6.Поясніть пошук заданого елемента масиву методом бінарного

пошуку.

7.Намалюйте блок-схему алгоритму бінарного пошуку.

8.Поясніть алгоритм сортування масиву методом швидкого сортування.

9.Поясніть алгоритм сортування масиву методом Шелла.

10.Поясніть алгоритм сортування масиву методом злиття.

Теоретичні відомості АЛГОРИТМИ ПОШУКУ

Пошук - процес відшукання інформації в множині даних (зазвичай представляють собою записи) шляхом перегляду спеціального поля в кожному записі, званого ключем. Метою пошуку є знаходження запису (якщо він є) з даним значенням ключа.

Існує безліч різних алгоритмів пошуку, що принципово залежать від способу організації даних.

Знайти елемент в масиві означає вказати його індекс, або дати зрозуміти, що такого елемента немає. Індексація у масивів буде [1..n], тому якщо елемента в масиві немає, то будемо вважати, що його індекс = 0.

Припустимо, заданий масив цілих чисел А і число х, яке треба знайти. Найбільш природний спосіб пошуку заданого числа в масиві, - просто

порівнювати почергово кожен елемент A[i] з числом х. Цей метод називається послідовним пошуком.

Очевидно, що послідовний пошук - єдино можливий спосіб відшукати елемент у масиві, про внутрішню структуру якого нічого не відомо.

const n = 4; {n - кількість елементів масиву}

type Mas = array [1..n] of integer; {Оголошення нового типу} var

і: byte; А: Mas; x: integer; begin

writeln ('Введіть, будь ласка,', n, 'елементів масиву'); for i: = 1 to n do {введення елементів масиву}

read (A [i]);

writeln ('Вихідний масив');

for i: = 1 to n do {Вивід масиву А на екран} write (A [i], '');

writeln;

writeln ('Введіть число, індекс якого треба знайти'); readln (х);

for i: = 1 to n do

if (A [i] = x) then begin

writeln ('y елемента', x, 'індекс =', i); exit;

end;

writeln ('Елементу в масиві немає'); readln; end.

Упорядкованість масиву (за убуванням або зростанням) дозволяє скоротити час пошуку в багато разів. Нехай для визначеності масив буде відсортований за зростанням.

Ідея методу така: спочатку порівнюємо число х з центральним

елементом масиву А (Aцентр). Якщо х = Ацентр, то ми знайшли індекс числа х. Якщо х> Ацентр, то ясно, що елемент х, якщо він в масиві взагалі є, може лежати тільки в 2-й половині масиву, а якщо х < Ацентр, то х може лежати лише в першій частині масиву. Виходить, що за один етап алгоритму область

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

const n = 34; var

M: array [l..n] of integer; i, s: byte;

x: integer;

r, l, h: integer; zahl: integer; begin

randomize;

М [1]: = 1;

for i: = 2 to n do

M [i]: = random (10) + M [i-1]; writeln ('Вихідний масив');

for i: = 1 to n do

write (M [i], 1 '); writeln;

write ('Введіть число, яке треба знайти'); readln (zahl);

{----------- бінарний пошук -------------} l: = 1; {Ліва межа області пошуку}

r: = n; {Права межа області пошуку}

while (l <= r) do {Поки кордони не перетнулися} begin

h: = (r + l) div 2;

if (M [h] = zahl) then begin

writeln ('Індекс числа', zahl, '=', h); readln;

exit;

end;

if M [h]> zahl then

r: = h-1 {вибираємо ліву половину області пошуку}

else

l: = h + 1; {вибираємо ліву половину області пошуку}

end;

writeln ('Числа', zahl, 'в масиві немає'); readln;

end.

СОРТУВАННЯ МАСИВУ

Оскільки впорядкованість масиву значно прискорює пошук елементів, то сортування масиву стає першочерговою проблемою. Для того щоб сортувати масиви є багато методів, що розрізняються за швидкістю роботи. Найпростіші алгоритми («бульбашкове» сортування, сортування вибором і сортування вставками) працюють за час cn2, де n - довжина масиву, а с - деяка константа. Вони дуже повільні при великих n, але для маленьких масивів вони працюють досить швидко.

Для сортувань великих масивів застосовуються більш швидкі сортування (сортування злиттям, Шелла, швидке сортування), що працюють за cnlog2n дій. Дуже хороші результати показує швидке сортування.

Удеяких випадках можна застосовувати комбіновані сортування. 1. Сортування методом бульбашки (обміну)

2. Сортування методом вибору

3. Сортування методом вставок

Увсіх трьох алгоритмів є одна схожість: масив ділиться на 2 частини - відсортовану і невідсортовану, причому з кожним кроком зовнішнього циклу кількість відсортованих елементів збільшується на 1. Надалі для визначеності будемо вважати, що масив треба впорядкувати за зростанням.

Сортування методом обміну («бульбашкове сортування»)

Алгоритм заснований на наступному спостереженні: якщо два елементи стоять не в потрібному порядку і якщо їх поміняти місцями, то масив стане більш впорядкованим, ніж раніше. Стало бути, щоб відсортувати масив, треба тільки визначити порядок, в якому будуть обмінюватися місцями елементи. Самий простий алгоритм такий: порівнюємо перший елемент з другим, потім - другий з третім і т.д. до кінця масиву. В результаті, крім того, що впорядкованість масиву зросте, можна з упевненістю сказати, що найбільший елемент точно буде знаходитися в кінці масиву (тобто на своєму місці). Тепер можна провести ще одну таку саму серію обмінів, тільки пробігати можна до передостаннього елемента, тому що останній вже знаходиться на своєму місці.

uses Crt; const n = 100; var

M: array [1..n] of integer; i, j: word;

tmp: integer; begin

Clrscr;

randomize;

for i: = 1 to n do

M [i]: = random (100); writeln ('Вихідний масив:'); for i: = 1 to n do

write (M [i], ''); writeln;

{сортування}

for j: = n-1 downto 1 do {j - межа області сортування}

for i: = 1 to j do {Прохід по поточній області сортування}

if M [i]> M [i + 1] then {Якщо необхідний порядок порушується, то переставляємо місцями елементи }

begin

tmp: = M [i + 1]; M [i + 1]: = M [i]; M [i]: = tmp;

end;

writeln ('Відсортований масив'); for i: = 1 to n do

write (M [i], ''); readln;

end.

Сортування вибором

На першому кроці шукається мінімальний елемент в масиві, і змінюється з першим елементом масиву. Після цього перший елемент вже знаходиться на своєму місці. Потім шукається елемент, який буде найменшим серед всіх елементів масиву, крім першого. Цей елемент обмінюється місцями з другим елементом масиву і т.д.

uses Crt; const

n = 100; var

M: array [1..n] of integer; i, j: word;

tmp: integer; ind: word; begin

Clrscr;

randomize;

for i: = 1 to n do

M [i]: = random (1000); writeln ('Вихідний масив:'); for i: = 1 to n do

write (M [i], ' '); writeln;

{сортування}

for i: = 1 to n-1 do {Зовнішній цикл змінює область сортування} begin

ind: = i; {індекс мінімального елемента}

for j: = i + 1 to n do {Проходимо по області пошуку}

if M [j] <M [ind] then {Якщо знайшли елемент менше

M[ind]}

ind: = j; {Запам'ятовуємо індекс мінімального елемента}

tmp: = M [ind]; {міняємо місцями мінімальний елемент і

M[i]}

M [ind]: = M [i]; M [i]: = tmp;

end;

writeln ('Відсортований масив'); for i: = 1 to n do

write (M [i], ' '); readln;

end.

Сортування вставками

Сортування вставками нагадує розстановку карт за старшинством: беремо поспіль всі карти, для кожної з них шукаємо підходяще місце і вставляємо її на це місце.

У сортуванні вставками масив розбивається на 2 частини: відсортовану (вона буде перебувати на початку масиву) і невідсортовану (інша частина масиву). Спочатку відсортована частина масиву - це перший елемент. Далі по черзі вибираються елементи з не відсортованої частини, після чого для них шукається місце у відсортованій частині. Коли для елемента місце знайдено, його треба звільнити. Для цього всі елементи, починаючи з цього індексу, треба зрушити вправо на одиницю. Після цього елемент можна вставити на його місце і перейти до наступного числа.

uses Crt; const

n = 100; var

M: array [1..n] of integer; i, j, k: word;

tmp: integer; begin

Clrscr;

randomize;

for i: = 1 to n do

M [i]: = random (1000); writeln ('Вихідний масив:'); for i: = 1 to n do

write (M [i], ' '); writeln;

{сортування}

for i: = 2 to n do begin

tmp: = M [i]; j: = 1;

while tmp> M [j] do {шукаємо місце, куди треба вставити M[i]}

j: = J + 1;

for k: = i-1 downto j do {Зрушуємо елементи масиву} M [k + 1]: = M [k]; {щоб звільнити місце для M

[i]}

M [j]: = tmp; {Вставляємо елемент на потрібну позицію}

end;

writeln ('Відсортований масив'); for i: = 1 to n do

write (M [i], ''); readln;

end.

Метод Шелла

Сортування Шелла отримало свою назву по імені творця Д.Л. Шелла. Загальний метод, який використовує сортування включенням та

застосовує принцип зменшення відстані між порівнюваними елементами. Нехай h - ціле від 1 до n/2. Незалежно один від одного упорядковуються

під послідовності з елементів, віддалених один від одного на h позицій:

Xi, Xi + h, Xi + 2h, Xi + 3h, ... (i = 1, 2, ..., h)

Потім h зменшується і процес повторюється заново. Останній крок обов'язково повинен бути виконаний при h = 1.

Значення h можна міняти різними способами, один з них такий: спочатку h рівне (цілій частині від) n/2, а потім h щораз зменшується вдвічі.

У таблиці 1 показана схема виконання сортування Шелла. Спочатку упорядковано всі елементи, які зміщені один від одного на чотири позиції. Потім сортуються всі елементи, які зміщені на дві позиції. І, нарешті, упорядковуються всі сусідні елементи.

Таблиця 1

Результати кожного етапу сортування Шелла

Початковий стан

Перший перехід

Другий перехід

Третій прохід

38

38

12

12

52

21

21

17

17

12

17

21

36

36

36

36

98

98

38

38

21

52

52

52

12

17

98

74

74

74

74

98

const N = 10;

var a: array [1..N] of integer;

p: boolean; {логічна змінна наявності перестановки} l, d, i, j: integer;

d: = N div 2; {Відстань між елементами масиву, що обробляються на кожному етапі алгоритму зменшується в 2 рази аж до 0, коли відбувається зупинка алгоритму}

while d> 0 do begin

for j: = 1 to Nd do {Перебір всіх пар елементів масиву, відстань між якими дорівнює d}

begin

l: = j {запам'ятовуємо індекс поточного елемента} repeat

p: = false; {поки елементи не переставлялися}

if a [l] <a [l + d] then begin {якщо порядок порушений, то}

c: = a [l]; a [l]: = a [l + d]; a [l + d]: = c; {міняємо місцями елементи

масиву}

l: = l-d; {перейдемо до тієї пари, в яку входить менший з переставлених елементів}

p: = true; {запам'ятаємо, що була перестановка} end;

until (l <= 1) and p; {продовжуємо, поки йдуть перестановки і не відбулося виходу за межі масиву}

end;

d: = d div 2; {Зменшимо відстань між порівнюваними елементами в 2

рази} end;

На перший погляд не можна сказати, що алгоритм дає хороший результат і навіть те, що в результаті вийде відсортований масив. Однак, він дає і те і інше. Ефективність цього алгоритму пояснюється тим, що при кожному проході використовується відносно невелике число елементів, або елементи масиву вже знаходяться у відносному порядку, а впорядкованість збільшується при кожному новому перегляді даних. Відстані між