
- •Найпростіші методи побудови таблиць ідентифікаторів
- •Побудова таблиць ідентифікаторів за методом бінарного дерева
- •Побудова таблиць ідентифікаторів на основі хеш-функцій
- •Мал.2.4. Заповнення таблиці індефікаторів при використанні найпростішого рехешерування
- •Побудова таблиць ідентифікаторів за методом ланцюжків
- •Мал.2.5.Заповнення хеш-таблиці і таблиці індефікаторів при використанні метода ланцюжків
- •Комбіновані способи побудови таблиць ідентифікаторів
Мал.2.4. Заповнення таблиці індефікаторів при використанні найпростішого рехешерування
Навіть такий примітивний метод рехешірованія є досить ефек ¬ вим засобом організації таблиць ідентифікаторів при приватному заповненні таблиці. Маючи, наприклад, заповнену на 90% таблицю для 1024 ідентифіка ¬ торів, в середньому необхідно виконати 5.5 порівнянь для пошуку одного іден ¬ тіфікатора, у той час як навіть логарифмічний пошук дає в середньому від 9 до 10 порівнянь. Порівняльна ефективність методу буде ще вище при зростанні числа ідентифікаторів і зниженні заповнювання таблиці. Середній час на приміщення одного елемента в таблицю і на пошук елемента в таблиці можна знизити, якщо застосувати більш досконалий метод рехешіро ¬ вання. Одним з таких методів є використання як р, для функ ¬ ції h, (A) = (h (A) + р,) mod Nm послідовності псевдовипадкових цілих чисел рь р2, Pk. При хорошому виборі генератора псевдовипадкових чисел довжина послідовності до буде к = Nm.Тоді середній час пошуку одного елемента в таблиці можна оцінити таким чином [17]:
E "= 0 ((l / Lf) * log2 (l - Lf)).
Існують і інші методи організації функцій рехешірованія h, (A), осно ¬ ванні на квадратичних обчисленнях або, наприклад, на обчисленні за форму ¬ ле: h ^ A) = (h (A) * i) mod Nm, якщо Nm - просте число.В цілому рехешірованіе дозволяє досягти непоганих результатів для ефективного пошуку елемента з таблиці (кращих, ніж бінарний пошук і бінарне дерево), але ефективність методу сильно залежить від заповнювання таблиці ідентифікаторів і якості використовуваної хеш-функції - чим рідше виникають колізії,тим вище ефек ¬ тивність методу.Вимога часткового заповнення таблиці веде до нееффек ¬ тивно використання обсягу пам'яті.
Побудова таблиць ідентифікаторів за методом ланцюжків
Часткове заповнення таблиці ідентифікаторів при застосуванні хеш-функцій веде до неефективного використання всього обсягу пам'яті, доступного ком ¬ пілятору.Причому обсяг невикористовуваної пам'яті буде тим вище, чим більше шформаціі зберігається для кожного ідентифікатора. Цього недоліку можна уникнути, якщо доповнити таблицю ідентифікаторів деякої проміжної \ еш-таблицею.
В осередках хеш-таблиці може зберігатися або пусте значення, або значення покажчика на деяку область пам'яті з основної таблиці ідентифікаторів.Тоді хеш-функція обчислює адресу, за якою відбувається звернення снача ¬ ла до хеш-таблиці, а потім вже через неї по знайденому адресою - до самої табли ¬ Це ідентифікаторів. Якщо відповідна клітинка таблиці ідентифікаторів порожня, то осередок хеш-таблиці міститиме порожнє значення.Тоді зовсім не обов'язково мати в самій таблиці ідентифікаторів клітинку для кожного возмож ¬ ного значення хеш-функції - таблицю можна зробити динамічної так, щоб її обсяг зростав у міру заповнення (спочатку таблиця ідентифікаторів не містить жодної клітинки,а всі комірки хеш-таблиці мають пусте значення).Такий підхід дозволяє домогтися двох позитивних результатів: по-перше, немає необхідності заповнювати порожніми значеннями таблицю ідентифікаторів - це можна зробити тільки для хеш-таблиці;по-друге, кожному ідентіфікато ¬ ру буде відповідати строго один осередок в таблиці ідентифікаторів (у ній не буде порожніх невикористовуваних осередків).Порожні комірки в такому випадку будуть тільки в хеш-таблиці, і обсяг невикористовуваної пам'яті не буде залежати від об'єк ¬ ема інформації, що зберігається для кожного ідентифікатора, - для кожного значення ¬ ня хеш-функції буде витрачатися тільки пам'ять,необхідна для зберігання ¬ ня одного покажчика на основну таблицю ідентифікаторів.На основі цієї схеми можна реалізувати ще один спосіб організації таблиць ідентифікаторів за допомогою хеш-функцій, званий «метод ланцюжків». Для методу ланцюжків у таблицю ідентифікаторів для кожного елемента додається ще одне поле, в якому може міститися посилання на будь-який елемент таблиці.Спочатку це поле завжди порожнє (нікуди не вказує). Також для цього методу необхідно мати одну спеціальну змінну, яка завжди укази ¬ кість на першу вільну комірку основної таблиці ідентифікаторів (першо ¬ початково - вказує на початок таблиці).
Метод ланцюжків працює за наступним алгоритмом:
Крок 1. У всі комірки хеш-таблиці помістити порожнє значення, таблиця иденти ¬ фікаторов порожня, мінлива FreePtr (покажчик першої вільної комірки) ука ¬ ють на початок таблиці ідентифікаторів; i: = 1.
Крок 2.Обчислити значення хеш-функції п, для нового елемента А,. Якщо ячей ¬ ка хеш-таблиці за адресою п, порожня, то помістити в неї значення змінної FreePtr і перейти до кроку 5; інакше перейти до кроку 3.
Крок 3.Покласти j: = 1, вибрати з хеш-таблиці адресу комірки таблиці иденти ¬ фікаторов mj і перейти до кроку 4.
Крок 4. Для комірки таблиці ідентифікаторів за адресою irij перевірити значення поля посилання. Якщо воно порожнє, то записати в нього адресу з перемінної FreePtr і пе ¬ рейти до кроку 5;інакше j: = j + 1, вибрати з поля посилання адреса т, і повторити крок 4. Крок 5. Додати в таблицю ідентифікаторів новий осередок, записати в неї ін ¬ формацію для елемента А, (поле посилання повинне бути порожнім), в змінну FreePtr помістити адресу за кінцем доданої комірки.Якщо більше немає іден ¬ тіфікаторов, які треба розмістити в таблиці, то виконання алгоритму за ¬ скінчено, інакше i: - i + 1 і перейти до кроку 2.
Пошук елемента в таблиці ідентифікаторів, організованої таким чином, буде виконуватися за наступним алгоритмом:
Крок 1.Обчислити значення хеш-функції п для шуканого елемента А. Якщо комірка хеш-таблиці за адресою п порожня, то елемент не знайдений і алгоритм завер ¬ шен, інакше покласти j: = 1, вибрати з хеш-таблиці адресу комірки таблиці іден ¬ тіфікаторов rrij .
Крок 2.Порівняти ім'я елемента в комірці таблиці ідентифікаторів за адресою т, з ім'ям шуканого елемента А. Якщо вони збігаються, то шуканий елемент знайдений і алгоритм завершений, інакше перейти до кроку 3.
Крок 3. Перевірити значення поля посилання в комірці таблиці ідентифікаторів за адресою irij.Якщо воно порожнє, то шуканий елемент не знайдений і алгоритм завершений, інакше j: = j + 1, вибрати з поля посилання адреса т, і перейти до кроку 2.При такій організації таблиць ідентифікаторів у разі виникнення кол ¬ лізіі алгоритм розміщує елементи в осередках таблиці, пов'язуючи їх одне з дру ¬ гом послідовно через поле посилання. При цьому елементи не можуть потрапляти в осередку з адресами,які потім будуть збігатися зі значеннями хеш-функції.Таким чином, додаткові колізії не виникають. У результаті в таблиці воз ¬ ника своєрідні ланцюжки пов'язаних елементів, звідки походить і назва ¬ ня даного методу - «метод ланцюжків».
На рис. 2.5 проілюстровано заповнення хеш-таблиці і таблиці ідентифі ¬ Каторі для прикладу, який раніше був розглянутий на рис. 2.4 для методу про ¬ стейшего рехешірованія.Після розміщення в таблиці для пошуку ідентифіка ¬ тора А1 потрібно 1 порівняння, для А2 - 2 порівняння, для A3 - 1 порівняння, для А4 - 1 порівняння і для А5 - 3 порівняння (порівняйте з результатами простого ре ¬ хешування).
Метод ланцюжків є дуже ефективним засобом організації таблиць ідентифікаторів. Середній час на розміщення одного елемента і на пошук елементу в таблиці для нього залежить тільки від середнього числа колізій, возникающих при обчисленні хеш-функції.Накладні витрати пам'яті, пов'язані з необхідністю мати одне додаткове поле покажчика в таблиці иденти ¬ фікаторов на кожен її елемент, можна визнати цілком виправданими. Цей метод дозволяє більш економно використовувати пам'ять,але вимагає організації роботи з динамічними масивами даних.