Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Л.р._4.doc
Скачиваний:
23
Добавлен:
04.03.2016
Размер:
105 Кб
Скачать

3. Пошук елемента в масиві.

Задача пошуку елемента в послідовності - одна з важливих задач програмування як з теоретичної, так і практичної точок зору. Ось її формулювання:

Нехай A = {a1, a2, ...} - послідовність однотипних елементів і b - деякий елемент, який володіє властивістю P. Знайти місце елемента b в послідовності А. Оскільки представлення послідовності в пам’яті може бути здійснено в виді масиву, задачі можуть бути уточнені як задачі пошуку елемента в масиві A:

1.Знайти максимальний елемент масиву;

2.Знайти даний елемент масиву;

3.Знайти k-тий за величиною елемент масиву;

Найбільш прості і часто оптимальні алгоритми основані на послідовному перегляді масиву A з перевіркою властивості P на кожному елементі.

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

Рrogram MinItem;

Const n = 23;

Var A : Array [1..n] of Real;

Min, Item : Real; Index, i : Integer;

Begin

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

Index := 1; Min := A[1];

For i := 1 to n do begin

Item := A[i];

If Min > Item

then begin Index := i; Min := Item end

end;

{Виведення значень Index, Min}

End.

Змінна Item введена для того, щоб уникнути повторних обчислень індексного виразу в A[i]. Ми пропонуємо читачу розглянути поведінку цього алгоритму і його модифікації у випадку, коли мінімальних елементів у масиві декілька і треба знайти перший, останній, а також всі мінімальні елементи.

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

4. Постановка задачі сортування.

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

Цікаво, що задача сортування є ідеальним прикладом великої кількості різноманітних алгоритмів, розв’язування одної і тої ж задачі. Розглядаючи різні методи сортування, ми побачимо, як зміна алгоритму приводить до нових, більш ефективних у порівнянні з простими, розв’язувань задачі сортування.

Крім цього, послідовності можна представити (реалізувати) в пам’яті різними структурами даних. Як і слід очікувати, ефективність алгоритмів стає дуже залежною від реалізації послідовності.

Нехай дана послідовність елементів a1, a2, ... , an. Елементи цієї послідовності - дані довільного типу, на якому визначено відношення порядку “<<” (менше) таке, що будь-які два різні елементи можна порівняти.

Сортування означає перестановку елементів послідовності ak1, ak2, ... , akn таку, що ak1 << ak2 << ... << akn.

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

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

Якщо послідовність a1, a2, ... , an реалізована як масив А[1..n], вся вона розміщена в адресованій пам’яті. Тому наряду з вимогами ефективності за часом основна вимога - економне використання пам’яті. Це означає, що алгоритм не повинен використовувати додаткові масиви і пересилки з масиву А в ці масиви.

Постановка задачі сортування в загальному виді передбачає, що існують тільки два типи дій з даними сортованого типу : порівняння двох елементів (x << y) і пересилання елемента (x := y). Тому зручна міра складності алгоритму сортування масиву А[1..n] за часом - кількість порівнянь C(n) і кількість пересилань M(n).

Прості алгоритми сортування.

Прості алгоритми сортування можна класифікувати як сортування обміном, сортування вибором і сортування вставками.

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

Основна дія сортування обмінами - порівняння двох елементів і, якщо результат порівняння від’ємний, перестановка їх місцями:

Якщо при i < j a[i] > a[j] то переставити a[i] і a[j].

В найбільш простому варіанті порівнюються елементи a[j] і a[j+1], що стоять поряд:

Приклад 3.

Program BublSort;

Const n = 100;

Var a : array[1..n] of Real;

i, j : Integer;

TempMem : Real;

Begin

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

For i := n - 1 downto 1 do

For j := 1 to i do

If a[j] > a[j+1]

then begin

TempMem := a[j+1]; a[j+1] := a[j]; a[j] := TempMem end;

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

End.

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

Приклад 4.

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

For i := 1 to n - 1 do begin

k := Індекс( Min(a[i], ..., a[n]));

Переставити a[i], a[k]

end;

Program SelectSort;

Const n = 10;

Var a : array[1..n] of Real;

i, j, MinIndex : Integer;

TempMem : Real;

Begin

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

For i := 1 to n - 1 do begin

{ пошук мінімального елемента }

MinIndex := i;

for j := i + 1 to n do

If a[j] < a[MinIndex] then MinIndex := j;

{перестановка елементів}

TempMem := a[MinIndex]; a[MinIndex] := a[i]; a[i] := TempMem

end;

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

End.

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

Ще один простий алгоритм сортування - сортування вставками базується на наступній ідеї: припустимо, що перші 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;

Var A : array[1..n] of Integer;

k : Integer;

l, r, i, j : Integer;

b : Integer;

Begin

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

For k := 1 to n-1 do begin

b := A[k+1];

If b < A[k]

then 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);{ Зсув “хвоста” масиву на 1 позицію праворуч}

For i := k downto j do A[i+1] := A[i];

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

end

end;

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

End.

Оцінимо ефективність алгоритму. Пошук міста елемента 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)

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