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

8.1. Приоритетный тип данных резюме очереди 323

Сравнение ключей с полными заказами

Приоритетной очереди нужно правило сравнения, которое никогда не противоречит себе. Для правила сравнения, которое мы обозначаем£, чтобы быть прочными таким образом, он должен определить

полное отношение заказа, которое должно сказать, что правило сравнения определено для каждого

пара ключей и это должно удовлетворить следующие свойства:

Собственность Reflexive: k£ k

Антисимметричная собственность: если k1£ k2 и k2£ k1, то k1 = k2 Переходная собственность: если k1£ k2 и k2£ k3, то k1£ k3 Любое правило сравнения,£, который удовлетворяет эти три свойства, никогда не приводит к a

противоречие сравнения. Фактически, такое правило определяет линейные отношения заказа

среди ряда ключей. Если конечной коллекции ключей определили полный заказ для него, то

понятие самого маленького ключа, kmin, хорошо определено как ключ, такой что kmin £ k,

для любого другого ключа k в нашей коллекции.

Приоритетная очередь - контейнер элементов, каждый связанный с ключом. Название «приоритетная очередь» происходит от факта, что ключи решают, что «приоритет» раньше выбирал элементы, которые будут удалены. Фундаментальные функции приоритетной очереди P следующие:

вставка (e): Вставьте элемент e (с неявным связанным значением ключа)

в P.

минута (): Возвратите элемент P с самым маленьким связанным ключом

стоимость, то есть, элемент, ключ которого меньше чем или равен тому из любого элемента в P.

removeMin (): Удалите из P минуту элемента (). Обратите внимание на то, что больше чем у одного элемента может быть тот же самый ключ, который является, почему мы старались определить removeMin, чтобы удалить не только любой минимальный элемент, но и тот же самый элемент, возвращенный минутой. Некоторые люди обращаются к функции removeMin как extractMin.

Есть много заявлений, где операционная вставка и removeMin играют важную роль. Мы рассматриваем такое заявление в примере, который следует. Пример 8.1: Предположим, что определенный flight полностью заказан час до отъезда. Из-за возможности отмен авиакомпания поддерживает приоритетную очередь резервных пассажиров, надеющихся получить место. Приоритет каждого пассажира, удерживают - добытый оплаченным проездом, частое - fl ваш статус, и время, когда пассажир введен в приоритетную очередь. Когда пассажир просит к fly резерву, asso-ciated пассажирский объект вставлен в приоритетную очередь с операцией по вставке. Незадолго до flight отъезда, если места становятся доступными (например, из-за отмен на последней минуте), авиакомпания неоднократно удаляет резервного пассажира с первоочередной задачей от приоритетной очереди, используя комбинацию минуты и removeMin операций, и позволяет этому совету людей.

324 Глава 8. Кучи и приоритетные очереди

8.1.2 Компараторы

Важная проблема в приоритетной очереди ADT, который мы до сих пор оставили неопределенными

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

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

Лучший подход должен был бы проектировать приоритетную очередь как templated класс, где тип элемента определен абстрактным аргументом шаблона, скажите E. Мы предполагаем, что каждый конкретный класс, который мог служить элементом нашей приоритетной очереди, обеспечивает средство для сравнения двух объектов типа E. Это могло быть сделано во многих отношениях. Возможно, мы требуем, чтобы каждый объект типа E обеспечил функцию, вызванную аккомпанемент, который сравнивает два объекта типа E и определяет, который больше. Возможно, мы требуем, чтобы программист определил функцию, которая перегружает C ++ оператор сравнения» <» для двух объектов типа E. (Раздел 1.4.2 Отзыва для обсуждения оператора, перегружающего). В C ++ жаргон это называют объектом функции.

Давайте рассмотрим более конкретный пример. Предположим, что класс Point2D определяет двумерный пункт. У этого есть две общественных членских функции, getX и getY, которые получают доступ к его x и координатам y, соответственно. Мы могли определить лексикографический менее - чем оператор следующим образом. Если координаты x отличаются, мы используем их относительные значения; иначе, мы используем относительные значения координат y.

оператор bool <(константа Point2D& p, константа Point2D& q)

если (p.getX () == q.getX ()) возвратите p.getY () <q.getY ();

еще возвратите p.getX () <q.getX ();

Этот подход перегрузки относительных операторов достаточно общий для

много ситуаций, но это полагается при условии, что объекты того же самого типа всегда сравниваются таким же образом. Есть ситуации, однако, где это - de - sirable, чтобы применить различные сравнения с объектами того же самого типа. Рассмотрите следующие примеры.

Пример 8.2: есть по крайней мере два способа сравнить C ++ строки символов,

«4» и «12». В лексикографическом заказе, который является расширением альфы - betic заказывающий строкам символов, мы имеем «4»> «12». Но если мы интерпретируем эти последовательности как целые числа, тогда «4» <«12».