Анимация
JavaScript
|
Главная Библионтека Вывод и удаление одного элемента cout « q.popC) « endl: catch (const exceptions e) { cerr « "EXCEPTION: " « e.whatC) « endl: При последнем вызове pop() намеренно допущена ошибка. В отличие от стандартного класса очереди с неопределенным поведением наш класс генерирует исключение. Результат выполнения программы выглядит так: These are four words! number of elements in the queue: 0 EXCEPTION: read empty queue Приоритетные очереди Класс priority queue<> реализует очередь, в которой последовательность чтения элементов определяется их приоритетами. По своему интерфейсу приоритетные очереди близки к обычным очередям: функция push() заносит элемент в очередь, а функции top() и рор() читают и удаляют следующий элемент (рис. 10,5). Однако в приоритетных очередях следующим элементом является пе первый вставленный элемент, а элемент с максимальным приоритетом. Таким образом, можно считать, что порядок сортировки элементов частично определяется их значениями. Как обычно, критерий сортировки может передаваться в параметре шаблона. По умолчанию элементы сортируются оператором < в порядке убывания; при этом следующим элементом всегда является элемент с максимальным приоритетом. Если существует несколько элементов с «максимальными» приоритетами, критерий выбора определяется реализацией. Рис. 10.5. Интерфейс приоритетной очереди Приоритетные очереди определяются в том же заголовочном файле <queue>, в котором определяются обычные очереди" linclude <queue> В файле <queue> класс priority queue определяется следующим образом: namespace std { template <class Т. class Container = vector<T>. class Compare = less<typename Container::value type > > class priority queue; Первый параметр шаблона определяет тип элементов. Необязательный второй параметр шаблона определяет контейнер, который будет использоваться внутренней реализацией приоритетной очереди для хранения элементов. По умолчанию это вектор. Необязательный третий параметр шаблона определяет критерий сортировки, который требуется для поиска следующего элемента с высшим приоритетом. По умолчанию элементы сравниваются оператором <. Например, следующее объявление определяет приоритетную очередь с элементами типа float: std:;priority queue<float> pbuffer: Приоритетная очередь для типа float Реализация приоритетной очереди просто отображает операции с очередью на соответствующие операции с используемым контейнером (см. рис. 10.4). Допускается использование любого класса последовательного контейнера с поддержкой функций итераторов произвольного доступа и функций front(), back(), push back() и pop back(). Произвольный доступ необходим для сортировки элементов, выполняемой алгоритмами STL для работы с кучей (см. с. 396). Например, элементы приоритетной очереди могут храниться в деке: std::priority queue<float.std::deque<float> > pbuffer: Чтобы определить собственный критерий сортировки, необходимо передать бинарный предикат в виде функции или объекта функции; предикат используется алгоритмами сортировки для сравнения двух элементов (за информацией о критериях сортировки обращайтесь на с. 186 и 296). Например, следующее объявление определяет приоритетную очередь с обратным порядком сортировки: std::pri ori ty queue<f1 oat.std::vector<f1oat>. std::greater<float> > pbuffer; В такой приоритетной очереди следующим элементом всегда является один из элементов с наименьшим значением. Основной интерфейс Основной интерфейс приоритетных очередей состоит из функций push(), top() и рор(): О функция push() вставляет элемент в приоритетную очередь; О функция top() возвращает следующий элемент приоритетной очереди; О функция рор() удаляет элемент из приоритетной очереди. В предыдущих версиях STL шаблону всегда передавался тип контейнера и критерий сортировки, поэтому объявление приоритетной очереди с элементами Ti-nia float выглядело так: priority queue<vector<float>.less<float> > buffer: Как и в остальных контейнерных адаптерах, функция рор() удаляет следующий элемент, но не возвращает его, тогда как функция top() возвращает следующий элемент без удаления. Следовательно, чтобы обработать и удалить следующий элемент очереди, всегда приходится вызывать обе функции. И, как обычно, если очередь не содержит ни одного элемента, поведение функций top() и рорО не определено. Наличие элементов в очереди проверяется фушсциями size() и empty(). Пример использования приоритетных очередей пример использования класса priority queue<>: cont/pqueuel.cpp #1nclude <1ostream> #1nclude <queue> using namespace std; int ma1nC) { priority queue<float> q; Вставка трех элементов в приоритетную очередь q.pushC66.6) q.push(22.2) q.push(44.4) Вывод и удаление двух элементов cout « q.topO « ; q.popO; cout « q.topO « endl; q.popC); Вставка еще трех элементов q.pushCU.O q.pushC55.5) q.pushC33.3) Удаление одного элемента q.popC); Извлечение и вывод оставшихся элементов while Oq.emptyC)) { cout « q.topO « : q.popC): cout « endl; Результат выполнения программы выглядит так: 66.6 44.4 33.3 22.2 11.1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 [ 140 ] 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |