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

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

обратитесь к тому же самому входу ведра. Это осуществлено в Кодовом Фрагменте 9.11.

/* HashMap K, V, H:: */ // iterators равны?

bool Iterator:: оператор == (константа Iterator& p) константа

если (ba! = p.ba скобка! = p.bkt) ложное возвращение;

еще, если (скобка == ba-> конец ()) верное возвращение;

еще возвратитесь (ent == p.ent);

// // //

ba или скобка отличаются? оба в конце? еще используйте вход, чтобы решить

Кодовый Фрагмент 9.11: операторы Iterator для тестирования равенства и приращения.

Затем, давайте полагать, что Iterator увеличивают оператора, показанного в Кодовом Frag-ment 9.12. Цель состоит в том, чтобы продвинуть iterator к следующему действительному доступу. Typ-ically, это включает продвижение к следующему входу в пределах текущего ведра. Но, если мы падаем с конца этого ведра, мы должны продвинуться к первому элементу следующего непустого ведра. Чтобы сделать это, мы сначала продвигаемся к следующему входу ведра, применяя оператора приращения STL на вход iterator ent. Мы тогда используем полезность func-tion endOfBkt, чтобы определить, прибыли ли мы в конце этого ведра. Если так, мы ищем следующее непустое ведро. Чтобы сделать это, мы неоднократно увеличиваем скобку и проверяем, упали ли мы с конца множества ведра. Если так, это - конец карты, и мы сделаны. Иначе, мы проверяем, пусто ли ведро. Когда мы сначала находим непустое ведро, мы перемещаем ent в первый вход этого ведра.

/* HashMap K, V, H:: */ //продвижение к следующему входу

Iterator& Iterator:: оператор ++ ()

++ ent;

//

следующий вход в ведре

если (endOfBkt (*this))

++ скобка;

в то время как (скобка! = ba-> конец () && скобка-> пустой ())

++ скобка;

// // //

в конце ведра? пойдите в следующее ведро, находят непустое ведро

если (скобка == ba-> конец ()) возвращаются *это;

ent = скобка-> начинаются ();

//конец множества ведра?//первый непустой вход

возвратитесь *это;

//возвратитесь сам

Кодовый Фрагмент 9.12: операторы Iterator для тестирования равенства и приращения.

Определения функций члена HashMap

Прежде, чем обсудить главные функции класса HashMap, давайте представим функции, начинаются и заканчиваются. Они даны в Кодовом Фрагменте 9.13. Конец функции - более простые из двух. Это включает создание iterator, компонент ведра которого - конец множества ведра. Мы не потрудились определять стоимость для части входа

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

iterator. Причина состоит в том что наш iterator тест на равенство (показана в Кодовом Фрагменте 9.11)

не потрудился сравнивать вход iterator ценности, если ведро iterators в конце множества ведра.

/* HashMap K, V, H:: */ //iterator, чтобы закончиться

Конец Iterator ()

возвращают Iterator (B, B.end ());/* HashMap K, V, H:: */ //iterator к фронту

Iterator начинаются ()

если (пустой ()) возвращают конец ();

Скобка BItor = B.begin ();

в то время как (скобка-> пустой ()) ++ скобка;

возвратите Iterator (B, скобка, скобка-> начинаются ());

// // // //

emtpty - возвратитесь конец еще ищут вход, находят, что непустое ведро возвращается сначала из ведра

Кодовый Фрагмент 9.13: функции HashMap, возвращаясь iterators к началу и концу карты.

Функция начинается, показанный в нижней части Кодового Фрагмента 9.13, более сложно, так как мы должны искать непустое ведро. Мы сначала проверяем, пуста ли карта. Если так, мы просто возвращаем конец карты. Иначе, начиная в начале множества ведра, мы ищем непустое ведро. (Мы знаем, что преуспеем в том, чтобы найти тот.), Как только мы находим его, мы возвращаем iterator, который указывает на первый вход этого ведра.

Теперь, когда мы представили iterator-связанные функции, мы готовы представить функции для класса HashMap. Мы начинаем с конструктора и sim - ple контейнерные функции. Конструктору дают способность множества ведра и создает вектор этого размера. Участник n отслеживает число записей. Они даны в Кодовом Фрагменте 9.14.

/* HashMap K, V, H:: */

HashMap (международная способность): n (0), B (способность)/* HashMap K, V, H:: */

международный размер () константавозвращает n;/* HashMap K, V, H:: */

пустые bool () константавозвращают размер () == 0;

//конструктор

//число записей

//действительно ли карта пуста?

Кодовый Фрагмент 9.14: конструктор и стандарт функционируют для HashMap.

Затем, мы представляем функции, связанные с нахождением ключей в верхней части Кодекса

Фрагмент 9.15. Большая часть работы сделана сервисным искателем функции. Это сначала применяет функцию мешанины, связанную с данным компаратором мешанины к ключу k. Это преобразовывает это в индекс во множество ведра, беря модуль стоимости мешанины

392

Глава 9. Хеш-таблицы, Карты и Списки Пропуска размер множества. Чтобы получить iterator к желаемому ведру, мы добавляем этот индекс к началу iterator множества ведра. (Мы используем факт, упомянутый в Разделе 6.1.4, что векторы STL обеспечивают произвольный доступ iterator, таким образом, дополнение позволено.) Позволяют скобке быть iterator к этому ведру. Мы создаем iterator p, который инициализирован к началу этого ведра. Мы тогда выполняем поиск входа, ключ которого соответствует k или пока мы не падаем с конца списка. В любом случае мы возвращаем окончательное значение iterator как результат поиска.

/* HashMap K, V, H:: */ //находят полезность

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

интервал i = мешанина (k) % B.size ();

Скобка BItor = B.begin () + я;

Iterator p (B, скобка, скобка-> начинается ());

в то время как (! endOfBkt (p) && (*p) .key ()! = k)

nextEntry (p);

// // // //

g и имеет h i ndex i ith запуск ведра ith поиска ведра k

возвратите p; //возвращают заключительное положение

/* HashMap K, V, H:: */ //находят ключ

Iterator находят (константа K& k)

Iterator p = искатель (k);

если (endOfBkt (p))

возвратите конец ();

еще

возвратите p;

//ищите k//, не находил его?//возвращение заканчивают iterator

//возвратите его положение

Кодовый Фрагмент 9.15: функции HashMap имели отношение к нахождению ключей.

Общественную членскую находку функции показывают в нижней части Кодового Frag-ment 9.15. Это призывает полезность искателя. Если компонент входа в конце ведра, мы знаем, что ключ не был найден, таким образом, мы возвращаем специальный конец iterator () до конца карты. (Таким образом все неудачные поиски приводят к тому же самому результату.) Это показывают в Кодовом Фрагменте 9.15.

Полезность вставки, вставку, показывают в верхней части Кодового Фрагмента 9.16. Этой полезности дают желаемое положение, в котором можно вставить новый вход. Это призывает функцию вставки списка STL, чтобы выполнить вставку. Это также увеличивает количество числа записей в карте и возвращает iterator к вставленному положению.

Общественная функция вставки, помещенная, сначала применяет искателя, чтобы определить, существует ли какой-либо вход с этим ключом в карте. Мы сначала определяем, не было ли это найдено, проверив ли iterator, как упали конец ведра. Если так, мы вставляем его в конце этого ведра. Иначе, мы изменяем существующую ценность этого входа. Позже, в Разделе 9.5.2, мы представляем альтернативный подход, который вставляет новый вход, даже когда двойной ключ обнаружен.

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

/* HashMap K, V, H:: */ //вставляют полезность

Вставка Iterator (константа Iterator& p, константа Entry& e)

EItor ins = p.bkt-> вставка (p.ent, e);

n + +;

возвратите Iterator (B, p.bkt, ins);

//вставка прежде p//еще один вход//возвращает это положение

/* HashMap K, V, H:: */ //вставляют/заменяют (v, k)

Итерэтор поместил (константа K& k, константа V& v)

Iterator p = искатель (k);

//поиск k

если (endOfBkt (p))

возвратите вставку (p, Вход (k, v));

еще

//k не найденный?//вставляют в конце ведра

//найденный им?

p.ent-> setValue (v);

возвратите p;

//замените стоимость v//, возвращают это положение

Кодовый Фрагмент 9.16: функции HashMap для вставки и замены записей.

Функции удаления также довольно прямые и даны в Кодовом Фрагменте 9.17. Главная полезность - резинка функции, которая удаляет вход в данном положении, призывая список STL, стирают функцию. Это также декременты число записей. Находящаяся в iterator функция удаления просто призывает резинку. Основанная на ключе функция удаления сначала применяет полезность искателя, чтобы искать ключ. Если не найдено, то есть, если возвращенное положение - конец ведра, исключение брошено. Иначе, полезность резинки призвана, чтобы удалить вход.

/* HashMap K, V, H:: */

недействительная резинка (константа Iterator& p)

p.bkt-> стирают (p.ent); n-;

/* HashMap K, V, H:: */

пустота стирает (константа Iterator& p)

резинка (p);/* HashMap K, V, H:: */

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

//удалите вход из ведра//один меньше входа

//удалите вход в p

//удалите вход с ключом k

пустота стирает (константа K& k)

Iterator p = искатель (k);

если (endOfBkt (p))

/ / fi без обозначения даты k//не найденный?

бросьте NonexistentElement («Стирают несуществующих»);//.. .error

резинка (p); //удаляют его

Кодовый Фрагмент 9.17: функции HashMap, связанного с удалением записей.