Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
4_Метод_вказівки_лаб_роб_Алгор_та_структ..doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
149.5 Кб
Скачать

1.5. Вставки в зв'язаний список

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

- перегляду вихідного файлу з порівнянням перемінної Х с елементами K[і] файлу;

-вставки нового елемента шляхом зрушення вправо елементів, що залишилися.

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

Дано файл у виді связанныого списку, кожен елемент якого містить крім ключа K[і] ще і покажчик на наступний елемент L[і].

Крім того є ще додаткова перемінна L[0], що містить покажчик на останній N-й елемент файлу. Покажчик L[N] дорівнює нулю, що є ознакою кінця списку елементів.

┌────┬────┐ ┌────┬────┐ ┌────┬────┐

│K[1]│L[1]├──>┤K[2]│L[2]├─>─ ... ──>┤K[N]│L[N]├─> =0

└────┴────┘ └────┴────┘ └──┬─┴────┘

┌┴───┐

│L[0]│

└────┘

Упорядкована частина файлу формується наприкінці списку і L[0] завжди вказує на початок упорядкованої частини, наприкінці алгоритму - на логічний початок списку.

Алгоритм має наступний вигляд:

for j=N-1 to 1

┌────────────────────────────────┐ q ┌─>─ p

│ p=L[0]; q=0; X=K[j]; │ ┌────┐ │ ┌────┐

│ │ │L[q]├─>─┘ │L[p]├─>─

│ ┌ while(p>0 & X>K[p]) ────┐ │ ├────┤ ├────┤

│ ├─────────────────────────┤ │ │K[q]│ │K[p]│

│ │ продвижение по списку │ │ └────┘ └────┘

│ ├─────────────────────────┤ │

│ │ q=p; p=L[p]; │ │

│ └─────────────────────────┘ │

│ ┌────────────────────────┐ │

│ │вставка │ │

│ ├────────────────────────┤ │

│ │ L[q]=j; L[j]=p; │ │

│ └────────────────────────┘ │

└────────────────────────────────┘

Перемінні p і q служать покажчиками на поточний елемент, причому p=l[q] (q завжди на один крок відстає від p). Якщо p=0, то Х - найбільший елемент і повинний потрапити в кінець списку. Час роботи алгоритму t приблизно оцінюється формулою:

t=a*N¤ + b*N

де a,b - невідомі константи, що залежать від програмної реалізації алгоритму.