Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Data Structures and Algorithms in C++ 2e (На ру...docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.37 Mб
Скачать

Глава 9. Хеш-таблицы, карты и списки пропуска

Мы определили ключевую роль Входа, чтобы быть «константой K», а не «K». Это предотвращает пользователя от непреднамеренного изменения ключа. Класс использует два главных типа данных. Первым является список STL записей, названных Ведром, каждый хранящий единственное ведро. Другой вектор STL ведер, названных BktArray.

Прежде, чем описать главные элементы класса, мы представляем некоторых местных (про - tected) утилиты в Кодовом Фрагменте 9.7. Мы объявляем три функции помощника, искателя, вставку и резинку, которые, соответственно, обращаются с деталями низкого уровня открытия, в - serting, и удаление записей. Для удобства мы определяем два типа iterator, один названный BItor для повторения по ведрам множества ведра и один названный EItor, для повторения по записям ведра. Мы также даем две сервисных функции, nextBkt и endOfBkt, которые используются, чтобы повторить посредством записей единственного ведра.

Искатель Iterator (константа K& k);

Вставка Iterator (константа Iterator& p, константа Entry& e); недействительная резинка (константа Iterator& p); typedef typename BktArray:: iterator BItor; typedef typename Ведро:: iterator EItor; статическая пустота nextEntry (Iterator& p)

++ p.ent;

//

// // // // //

найдите полезность

полезность вставки демонтирует сервисное ведро iterator вход iterator следующий вход ведра

статический bool endOfBkt (константа Iterator& p) //конец ведра?

возвращают p.ent == p.bkt-> конец ();

Кодовый Фрагмент 9.7: Декларации утилит, которые будут вставлены в HashMap.

Мы представляем класс Iterator в Кодовом Фрагменте 9.8. iterator должен хранить достаточно информации о положении входа, чтобы позволить ему проводить. Мадам - bers ent, скобка, и магазин ba, соответственно, iterator к текущему входу, ведро, содержащее этот вход и множество ведра, содержащее ведро. Первые два имеют типы EItor и BItor, соответственно, и третьим является указатель. Наш implementa-tion минимален. В дополнение к конструктору мы предоставляем операторам для dereferencing (» * «), проверяя равенство (» == «), и продвигаясь через карту (» ++ «).

класс Iterator

частный:

EItor ent; скобка BItor; константа BktArray* ba;

общественность:

//iterator (& положение)

//какой вход//, который ведро//, который множество ведра

Iterator (константа BktArray& a, константа BItor& b, константа EItor& q = EItor ())

: ent (q), скобка (b), ba (&a)

Entry& оператор* () константа; //получают вход

оператор bool == (константа Iterator& p) константа; //равный iterators? Iterator& оператор ++ (); //ссуды следующему другу входа класс HashMap; //предоставляют доступ HashMap

;

Кодовый Фрагмент 9.8: Декларация класса Iterator для HashMap.

9.2. Хеш-таблицы 389

Iterator Dereferencing и Condensed Function Definitions

Давайте теперь представим определения членских функций класса для нашей карты

Класс Iterator. В Кодовом Фрагменте 9.9, мы представляем внедрение deref-erencing оператор. Само тело функции очень просто и включает возвращение - луг ссылка на соответствующий вход. Однако правила C ++ синтаксис de - mand экстраординарное число определителей шаблона. Во-первых, мы должны квалифицировать саму функцию, как являющуюся членом iterator класса HashMap, который мы делаем с определителем HashMap <K, V, H>:: Iterator. Во-вторых, мы должны квалифицировать тип возвращения func-tion, как являющийся классом входа HashMap, который мы делаем с определителем HashMap <K, V, H>:: Вход. Вдобавок к этому мы должны вспомнить из Раздела 8.2.1, что, так как мы используем параметр шаблона, чтобы определить тип, мы должны включать ключевое слово typename.

шаблон <typename K, typename V, typename H>//получает вход typename HashMap<K,V,H>::Entry& HashMap <K, V, H>:: Iterator:: оператор* () константа

возвращаются *ent;

Кодовый Фрагмент 9.9: оператор Iterator dereferencing (заполняют форму).

Чтобы сделать наши определения функции более удобочитаемыми, мы принимаем письменное соглашение в некоторых наших будущих кодовых фрагментах определения определителя обзора для кодового фрагмента в курсивном синем шрифте. Мы опускаем этот определитель из кодекса frag-ment, и мы также опускаем заявление шаблона и typename технические требования. Добавление их отступает, простое механическое осуществление. Хотя это не действительный C ++

Предостережение

синтаксис, это передает важное содержание намного большим сжатым способом. Экс-вполне достаточный из того же самого dereferencing оператора показан в Кодовом Фрагменте 9.10.

/* HashMap K, V, H:: */ //получают вход

Entry& Iterator:: оператор* () константа

возвращаются *ent;

Кодовый Фрагмент 9.10: тот же самый dereferencing оператор Кодового Фрагмента 9.9 в сжатой форме.

Определения других членских функций Iterator

Давайте затем рассмотрим оператора «оператора Iterator == (p)», который проверяет, равен ли этот iterator iterator p. Мы сначала проверяем, что они принадлежат тому же самому множеству ведра и тому же самому ведру в пределах этого множества. В противном случае iterators, конечно, отличаются. Иначе, мы проверяем, относятся ли они оба до конца множества ведра. (Так как мы установили, что ведра равны, это достаточно, чтобы проверить только одного из них.) Если так, они оба равны HashMap:: конец (). В противном случае мы проверяем ли они оба