Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
4 основи програмування книга.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.77 Mб
Скачать

8.4. Бінарний пошук в упорядкованому масиві

Приклад 8.6. Задача пошуку суттєво спрощується, якщо елементи масиву упорядковані. Стандартний метод пошуку в упорядкованому масиві – це ділення відрізка навпіл, причому відрізком є відрізок індексів 1..n. Насправді, нехай m (k < m < l) – деякий індекс. Тоді якщо A[m] > b, далі елемент треба шукати на відрізку k..m-1, а якщо A[m] < b - на відрізку m+1..l.

Для того, щоб збалансувати кількість обчислень в тому і іншому випадках, індекс m треба вибирати так, щоб довжини відрізків k..m, m..l були (приблизно) рівними. Описану стратегію пошуку називають бінарним пошуком.

Procedure BinarySearch (Var A: Vector; b : Real; Var m: Integer);

Var

Buf : Real;

k, l : Integer;

Begin

k := 1; l := n;

Repeat

m := (k + l) div 2;

Buf := A[m];

If Buf > b

then l := Pred(m)

else k := Succ(m)

until (Buf = b) or (l < k);

If A[m] <> b

then m:=0;

End;

Якщо елемент не знайдено, процедура повертає значення індексу рівне нулю.

Неважко отримати оцінку числа С (n) порівнянь методу, застосувавши формулу (1) прикладу 8.3. Нехай М - кількість повторень циклу. Тоді

М  [log2 (n)]

Оскільки на кожному кроку здійснюється 2 порівняння, у гіршому випадку

C(n) = 2[log2 n] = O(log2 n) (2)

8.5. Алгоритми сортування масивів (продовження). Сортування вставками

Ще один простий алгоритм сортування - сортування вставками базується на наступній ідеї: припустимо, що перші k елементи масиву A[1..n] вже упорядковані:

A[1]  A[2]  ...  A[k], A[k+1], ..., A[n]

Знайдемо місце елемента A[k+1] в початковому відрізку A[1],...,A[k] і вставимо елемент на своє місце, отримавши упорядковану послідовність довжини k+1. Оскільки початковий відрізок масиву упорядкований, пошук треба реалізувати як бінарний. Вставці елемента на своє місце повинна передувати процедура зсуву “хвоста” початкового відрізка для звільнення місця.

Program InsSort;

Const

n = 100;

Type Vector = array[1..n] of Integer;

Var

A : Vector

Procedure BinFind( Var A: Vector; b, k: Integer; Var j: Integer);

Var l, r, i : Integer;

Begin {Бінарний пошук}

l := 1;

r := k;

Repeat

j := (l + r) div 2;

If b < A[j]

then r := j

else l := j + 1;

until (l = j);

End;

Procedure Sort( Var A: Vector);

Var k, b, j, i : Integer;

Begin

For k := 1 to n-1 do begin

b := A[k+1];

If b < A[k]

then begin

BinFind(A, b, k, j );

For i := k downto j do A[i+1] := A[i]; {Зсув частини масиву на 1 праворуч}

A[j] := b ; { Пересилання елемента на своє місце}

end

end;

End;

Begin

{Блок читання масиву A}

Sort(A);

{Блок виведення масиву A}

End.

8.5.1 * Ефективність алгоритму

Оцінимо ефективність алгоритму. Пошук міста елемента A[k+1] потребує, як показано вище, O(log2 k ) порівнянь. Тому у гіршому випадку кількість порівнянь С (n) є

C(n) = O(log2 2 ) + ... + O(log2(n-1)) + O(log2 n) = O(n log2 n)

Зсув правої частини масиву на кожному кроці зовнішнього циклу у гіршому випадку потребує k перестановок. Тому у гіршому випадку

M(n) = 1 + ... + (n-2) + (n-1) = n*(n-1)/2 = O(n2)

Таким чином, алгоритм сортування вставками значно ефективніший, ніж всі розглянуті раніше алгоритми за числом порівнянь. Однак число перестановок у гіршому випадку також буде значним, як і у самому неефективному алгоритмі – сортуванню простими обмінами.