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

424 Глава 10. Деревья поиска

10.1 Деревья двоичного поиска

Все структуры, которые мы обсуждаем в этой главе, являются деревьями поиска, то есть, структуры данных дерева, которые могут использоваться, чтобы осуществить заказанный карты и заказываться словари. Вспомните из Главы 9, что карта - коллекция записей значения ключа с каждой стоимостью, связанной с отличным ключом. Словарь отличается, в котором многократные ценности могут разделить то же самое значение ключа. Наше представление сосредотачивается главным образом на картах, но мы рассматриваем обе структуры данных в этой главе.

Мы предполагаем, что карты и словари обеспечивают специальный объект указателя, названный iterator, который разрешает нам ссылаться и перечислять записи структуры. Чтобы указать, что объект не присутствует, там существует специальный страж iterator названный концом. В соответствии с соглашением, этот страж обращается к воображаемому элементу, который находится только вне последнего элемента структуры.

Позвольте M быть картой. В дополнение к стандартным контейнерным операциям (размер, пустой, начинаются, и конец) карта ADT (Раздел 9.1) включает следующее:

найдите (k): Если M содержит вход e = (k, v), с ключом, равным k, то

возвратите iterator p относящийся к этому входу, и иначе возвратите специальный конец iterator.

помещенный (k, v): Если у M нет входа с ключом равным k, то

добавьте вход (k, v) к M, и иначе, замените область стоимости этого входа с v; возвратите iterator к в - serted/modified вход.

сотрите (k): Удалите из M вход с ключом, равным k; ошибка

условие происходит, если у M нет такого входа.

сотрите (p): Удалите из M вход, на который ссылается iterator p;

состояние ошибки происходит, если p указывает до конца стражу.

начните (): Возвратите iterator к первому входу M.

конец (): Возвратите iterator к положению только вне конца M.

ADT словаря (Раздел 9.5) обеспечивает дополнительную операционную вставку (k, v), который вставляет вход (k, v), и findAll (k), который возвращает диапазон iterator (b, e) всех записей, значение ключа которых - k.

Учитывая iterator p, к связанному входу можно получить доступ, используя *p. К indi-vidual ключ и стоимость можно получить доступ, используя p-> ключ () и p-> стоимость (), соответственно. Мы предполагаем, что основные элементы оттянуты из полного заказа, который определен, перегрузив C ++ относительный меньше оператор (» <»). Учитывая iterator p к некоторому входу, это может быть продвинуто к следующему входу в этом заказе, используя оператора приращения (» ++ p»).

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

10.1. Деревья двоичного поиска 425

работа подобна той из находки. Так, мы сосредотачиваемся на находке как основной поиск

операция в этой главе.

Деревья двоичного поиска и заказанные карты

Двоичные деревья - превосходная структура данных для хранения записей карты, как -

суммирование нам определили отношение заказа на ключах. Как упомянуто ранее (Раздел 7.3.6), дерево двоичного поиска - двоичное дерево T таким образом, что каждый внутренний узел v T хранит вход (k, x) таким образом что:

• Ключи, сохраненные в узлах в левом поддереве v, меньше чем или равны k

• Ключи, сохраненные в узлах в правильном поддереве v, больше, чем или равны k.

Пример дерева поиска, хранящего ключи целого числа, показывают в рисунке 10.1.

44

17 88

32 65 97

28 54 82

29 76

80

Рисунок 10.1: дерево двоичного поиска T представление карты с ключами целого числа.

Поскольку мы показываем ниже, ключи, сохраненные в узлах T, обеспечивают способ за - формирование поиска, делая сравнения в серии внутренних узлов. Поиск может остановиться в текущем узле v или продолжиться в левом или правом ребенке v. Таким образом мы получаем представление здесь, что деревья двоичного поиска - непустые надлежащие двоичные деревья. Таким образом, мы храним записи только во внутренних узлах дерева двоичного поиска, и внешние узлы служат «заполнителями». Этот подход упрощает несколько из наших алгоритмов поиска и обновления. Случайно, мы могли допускать неподходящие деревья двоичного поиска, которые имеют лучшее космическое использование, но за счет более сложного поиска и обновляют функции.

Независимый от того, рассматриваем ли мы деревья двоичного поиска как надлежащие или нет, im-собственность предзнаменования дерева двоичного поиска - реализация заказанной карты (или словарь). Таким образом, дерево двоичного поиска должно иерархически представлять заказ - луг его ключей, используя отношения между родителем и детьми. Определенно, inorder пересечение (Раздел 7.3.6) узлов дерева двоичного поиска T должно посетить ключи в неуменьшающемся заказе. Увеличивание iterator через карту посещает записи в этом том же самом заказе.