Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Strukturi_danikh_ta_algoritmi_-_konspekt_lektsi...doc
Скачиваний:
33
Добавлен:
23.11.2019
Размер:
870.4 Кб
Скачать

2.2.4.Сортування Шелла

Це ще одна модифікація сортування бульбашкою. Суть її полягає в тому, що тут виконується порівняння ключів, віддалених один від одного на деяку відстань d. Початковий розмір d звичайно вибирається рівним половині загального розміру сортованої послідовності. Виконується сортування бульбашкою з інтервалом порівняння d. Потім величина d зменшується удвічі і знов виконується сортування бульбашкою, далі d зменшується ще удвічі і т.д. Останнє сортування бульбашкою виконується при d=1. Якісний порядок сортування Шелла залишається , середнє ж число порівнянь, визначене емпіричним шляхом, – N*log2(N)^2. Прискорення досягається за рахунок того, що виявленні „не на місці” елементи при d>1, швидше „спливають” на свої місця. Наступний приклад ілюструє сортування Шелла.

void Sort(int *a)

{

int d, i, t;

bool k; // ознака перестановки

d = N / 2; // початкове значення інтервалу

while (d>0) // цикл із зменшенням інтервалу до 1

{

k = true; // сортування бульбашкою з інтервалом d

while (k) // цикл, поки є перестановки

{

k = false;

for ( i=0; i<N-d; i++ ) // порівняння ел-тів на інтервалі d

if ( a[i] > a[i+d] )

{

Swap(a[i], a[i+d]); // перестановка

k = true; // ознака перестановки

};

};

d = d / 2; // зменшення інтервалу

};

}

2.3.Сортування включенням

2.3.1.Сортування простим включенням

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

Алгоритм сортування простим включенням ілюструється прикладом.

void Sort(int *a, int *b)

{

int i, j, k;

for ( i=0; i<N; i++ ) // перебір вхідного масиву

{

// пошук місця для в масиві виходу

j = 0;

while ((j<i) && (b[j]<=a[i]))

j++;

// звільнення місця для нового ел-та

for ( k=i; k>j; k-- )

b[k] = b[k-1];

b[j] = a[i]; // запис в масив виходу

};

}

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

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

2.3.2.Бульбашкове сортування включенням

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

void Sort (int *a)

{

int i, j, k, t;

for ( i=1; i<N; i++ ) // перебір вхідного масиву

{

// *** вх.множина - [і..N-1], вих.множина - [0..і]

t = a[i]; // запам'ятовується значення нового ел-та

j = i-1; //пошук місця для ел-та у вих. множині з зсувом

// цикл закінчиться досягши початку або,

// коли зустріне ел-т, менший нового

while ((j >= 0) && (a[j]>t))

a[j+1] = a[j--]; // всі ел-ти, більші нового зсовуються

// цикл від кінця до початку множини виходу

a[j+1] = t; // новий ел-т ставиться на своє місце

};

}

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]