
- •17. Проаналізувати роботу алгоритму лінійного пошуку в одномірному масиві.
- •19. Проаналізувати роботу алгоритму сортування обмінами "бульбашки".
- •I,j : Integer;
- •X : Item;
- •I,j,k: integer;
- •X: Item;
- •22. Навести визначення та властивості евристичних алгоритмів.
- •23. Навести опис евристичних алгоритмів для рішення задачі про упакування.
- •24. Навести опис, рекурсивно-визначені процедури і функції.
- •25. Навести опис складної рекурсії.
- •28. Навести визначення та способи зображення дерев.
- •29. Навести опис впорядкованого та бінарного дерева.
- •30.Навести алгоритм прямого порядку (preorder) обходу дерева.
- •31.Навести алгоритм зворотного порядоку (postorder) обходу дерева.
- •32. Навести алгоритм обходу дерева в кінцевому порядку.
- •35. Розкрити алгоритм пошуку у глибину (dfs).
- •36. Розкрити алгоритм пошуку у ширину.
- •37. Навести визначення, кістякове дерево зв'язаного неорієнтованого графа.
- •38. Сформулювати завдання про знаходження мінімального кістякового дерева
- •39. Розкрити алгоритм Краскала.
- •40. Проаналізувати роботу алгоритму Дейкстри.
- •41.Розкрити алгоритм флойда.
- •42.Навести метод розгалужень і меж
16. Загальні методи побудови алгоритмів.
Перший метод звязаний зі зведенням важкої задачі до послідовності більш простих задач. Звичайно, ми сподіваємося на те, що більш прості задачі легше піддаються обробці, чим первісна задача, а також на те, що рішення первісної задачі може бути отримане з рішень цих більш простих задач. Така процедура називається методом часткових цілей.
Цей метод виглядає дуже розумно. Але, як і більшість загальних методів рішення чи задач розробки алгоритмів, його не завжди легко перенести на конкретну задачу. Осмислений вибір більш простих задач — скоріше справа чи мистецтва інтуїції, чим науки. Більш того, не існує загального набору правил для визначення класу задач, які можна вирішити с допомогою такого підходу. Міркування над будь-якою конкретною задачею починається с постановки питань.
Другий метод розробки алгоритмів відомий як метод підйому. Алгоритм підйому починається с прийняття початкового чи припущення обчислення початкового рішення задачі. Потім починається наскільки можливо швидкий рух нагору від початкового рішення в напрямку до кращих рішень. Коли алгоритм досягає таку точку, з якої більше неможливо рухатися наверх, алгоритм зупиняється. На жаль, ми не можемо завжди гарантувати, що остаточне рішення, отримане с допомогою алгоритму підйому, буде оптимальним. Цей дефект часто обмежує застосування методу підйому. Узагалі методи підйому є грубими. Вони запамятовують деяку ціль і намагаються зробити усе, що можуть і де можуть, щоб підійти ближче до мети. Це робить їхній трохи недальновидними.
Третій метод, розглянутий у цьому розділі, відомий як відпрацювання назад, тобто починаємо з мети чи рішення і рухаємося назад у напрямку до початкової постановки задачі. Потім, якщо ці дії оборотні, рухаємося назад від постановки задачі до рішення. Найчастіше такий метод застосовується для розвязання геометричних задач.
17. Проаналізувати роботу алгоритму лінійного пошуку в одномірному масиві.
Лінійний пошук здійснюється циклом (while ) з подвійною умовою. Перша умова контролює індекс на приналежність масиву, наприклад, (i<=N). Друга умова - це умова пошуку. У нашому випадку в циклі while ця умова продовження пошуку: (A[i]<>X), (A[i]=X). У тілі циклу звичайно пишеться тільки один оператор: зміна індексу в масиві.
Після виходу із циклу необхідно перевірити, по якому з умов ми вийшли. В операторі if звичайно повторюють перша умова циклу. Можна говорити про успішний пошук із циклом while при виконанні цієї умови.
18. Проаналізувати роботу алгоритму бінарний пошук у впорядкованому одномірному масиві.
Алгоритм двійкового пошуку можна використати для пошуку елемента із заданою властивістю тільки в масивах, упорядкованих по цій властивості. Так при пошуку числа із заданим значенням необхідно мати масив, упорядкований по зростанню або по убуванню значень елементів. А, наприклад, при пошуку числа із заданою сумою цифр масив повинен бути впорядкований по зростанню або по убуванню сум цифр елементів.
Ідея алгоритму полягає в тому, що масив щораз ділиться навпіл і вибирається та частина, де може перебувати потрібний елемент. Розподіл триває поки частина масиву для пошуку більше одного елемента, після чого залишається перевірити цей елемент, що залишився, на виконання умови пошуку.
Існують дві модифікації цього алгоритму для пошуку першого й останнього входження. Все залежить від того, як вибирається середній елемент: округленням у меншу або більшу сторону. У першому випадку середній елемент ставиться до лівої частини масиву, а в другому - до правого.
У процесі роботи алгоритму двійкового пошуку розмір фрагмента, де цей пошук повинен тривати, щораз зменшується приблизно у два рази. Це забезпечує обчислювальну складність алгоритму порядку логарифма N по підставі 2, де N - кількість елементів масиву.
19. Проаналізувати роботу алгоритму сортування обмінами "бульбашки".
Це - найпростіший з методів сортування. Програма цього методу є найкоротшою з усіх можливих. Ідея полягає у тому, щоб на кожному кроці, порівнюючи сусідні елементи між собою, міняти їх місцями, якщо вони стоять "не в тому порядку". Таких проходів по масиву може знадобитися не менше, як (n-1), бо, якщо найменший елемент стоїть на останньому місці, то він досягне свого (першого) місця лише за n-1 крок сусідніх обмінів.
Procedure BubbleSort;
var
I,j : Integer;
X : Item;
begin
for i := 1 to n-1 do
for j := 2 to n do
if a[j-1].key > a[j].key then begin {обмін}
x := a[j];
a[j] := a[j-1];
a[j-1] := x;
end;
end;
Програма називається "булькове сортування", а метод - методом "бульбашки", бо, якщо вважати кінець масива таким, що знаходиться угорі, то складається враження під час роботи програми, що елементи піднімаються по масиву, як бульбашки у воді до поверхні. Ідея методу та його реалізація такі прості, що, скоріш за все, швидкісні характеристики його є найгіршими з усіх, що ми розглянули. Так воно і є.
Є багато способів поліпшити роботу алгоритму. Ми зробимо це, а потім проаналізуємо якість. По-перше, після першого ж проходу ( при i = 1) найбільший елемент одразу підніметься на своє місце - останнє. Тому внутрішній цикл можна робити лише до (n - i + 1). По-друге, якщо хоча б один елемент стоїть ще не на місці, то за черговий прохід буде зроблено принаймі один обмін. Тому, якщо за деякий прохід не зроблено жодного обміну, це означає, що масив уже відсортовано. Тому слід перед кожним проходом встановлювати деяку логічну змінну y, рівну, скажімо, true, а в середині, якщо робиться обмін, то y := false. Після проходу її слід аналізувати. Третю модіфікацію пов'язано з асиметриєю методу: якщо найбільший елемент потрапляє на місце лише за один прохід, то найменший - лише за n, якщо він стоїть на крайньому місці. Тому пропонується проходи здійснювати по-черзі в двох напрямках. Такий спосіб називається шейкер-сортування (shaker (англ.)).
Кількість порівнянь для "булькового методу":
обмінів:
Для шейкер-методу аналіз зробити складно. Але цей метод має сильну перевагу якщо масив "майже відсортовано", тобто, коли кількість елементів m, що не стоять на місці, є незначною у порівнянні з n, n бб m. Тоді їх буде розставлено рівно за m проходів.
20. Проаналізувати роботу алгоритму сортування за допомогою прямого вибору.
Сортування вибором — простий алгоритм сортування лінійного масиву, на основі вставок. Має ефективність n2, що робить його неефективним при сортування великих масивів, і в цілому, менш ефективним за подібний алгоритм сортування включенням. Сортування вибором вирізняється більшою простотою, ніж сортування включенням, і в деяких випадках, вищою продуктивністю. Алгоритм працює таким чином:
Знаходить у списку найменше значення
Міняє його місцями із першим значеннями у списку
Повторює два попередніх кроки, доки список не завершиться (починаючи з другої позиції)
Фактично, таким чином ми поділили список на дві частини: перша (ліва) — повністю відсортована, а друга (права) — ні. Сортування вибором не є складним в аналізі та порівнянні його з іншими алгоритмами, оскільки жоден з циклів не залежить від даних у списку. Знаходження найменшого елементу вимагає перегляду усіх n елементів (у цьому випадку n − 1 порівняння), і після цього, перестановки його до першої позиції. Знаходження наступного найменшого елементу вимагає перегляду n − 1 елементів, і так далі, для (n − 1) + (n − 2) + ... + 2 + 1 = n(n − 1) / 2 ∈ Θ(n2) порівнянь (дивітьсяарифметична прогресія). Кожне сканування вимагає однієї перестановки для n − 1 елементів (останній елемент знаходитиметься на своєму місці). Приклад:
procedure selection_sort(var a: array of Double; min, max : integer);
//a - динамічний масив типу Double; min, max - мінімальний та максимальний індекс масиву а.
var
i,j,k,m:Integer;
q:Double;
begin
j:=min;
m:=j;
k:=max
repeat
q:=a[j];
for i:=j to k do
if a[i]<q then
begin
m:=i;
q:=a[i];
end;
a[m]:=a[j];
a[j]:=q;
j:=j+1;
until j=k;
end;
21. Проаналізувати алгоритм сортування за допомогою прямого включення (вставкою). Один елемент завжди можна вважати відсортованим масивом довжини 1. Розглядаючи послідовно решту елементів масиву будемо включати їх у відсортовану частину масиву, ставлячи на потрібне місце, тобто не порушуючи відсортованості цієї частини. Повторивши операцію включення n-1 раз, одержимо відсортований масив.
На i-му кроці відсортованим вважається масив a[1] .. a[i], а вставляємо елемент a[i+1]. Вставляти можна, послідовно порівнюючи a[i+1] з a[1], a[2],..., поки не знайдеться "дірка" j
a[j] Ј a[i+1] Ј a[j+1].
Тоді слід зсунути елементи a[j+1] .. a[i] вправо на один елемент, а a[i+1] записати на місце a[j+1].
Може статися, що a[i+1] більше за будь-який з членів відсортованої частини. Тоді дірку не буде знайдено. Тому слід контролювати номер j, щоб не вийти за межи відсортованої частини.
Остаточно програма має вигляд
procedure StraightInsertion (var a : Items);
var