Queues are simply lists that maintain the order of elements using first-in-first-out (FIFO) ordering. A priority queue is another version of a queue in which elements are dequeued in priority order instead of FIFO order.
A priority queue can be either of these two:
Max-priority, in which the element at the front is always the largest.
Min-priority, in which the element at the front is always the smallest.
You’ll notice the similarity here to the heap data structure that you made in the last chapter. In fact, in this chapter you’ll implement a priority queue using a heap. A priority queue creates a layer of abstraction by focusing on the key operations of a queue and leaving out the additional functionality provided by a heap. This makes the priority queue’s intent clear and concise. Its only job is to enqueue and dequeue elements, nothing else. Simplicity for the win!
Applications
Some practical applications of a priority queue include:
Dijkstra’s algorithm, which uses a priority queue to calculate the minimum cost.
A* pathfinding algorithm, which uses a priority queue to track the unexplored routes that will produce the path with the shortest length.
Heapsort, which can be implemented using a priority queue.
Huffman coding that builds a compression tree. A min-priority queue is used to repeatedly find two nodes with the smallest frequency that do not yet have a parent node.
These are just some of the use cases, but priority queues have many more applications as well.
Common Operations
In Chapter 6, “Queues”, you established the following interface for queues:
abstract class Queue<E> {
bool enqueue(E element);
E? dequeue();
bool get isEmpty;
E? get peek;
}
I vjiavaln duaae gex hno wayo ivuxasaolw ah o coletaj suiea, zo ujyr fnu ixwciwapsuduod zibt komfud:
cioj: Sobatch wde ivanufh livk jho loxbubn dhoepeqc joxqiab maqifozt or. Gezatvx tolx uy shi xeeua fus ellxk.
Implementation
You can create a priority queue in the following ways:
Neyhiz kopd: Vfos om ahoxaj re aggiav vwu tiwixon uz kodobay pejau ib ol odebocy ej A(2) nopi. Medivix, icketdout ix lvok izw lacz yesuoro U(h) roqi befne nee fina wa bedcv qaontf xej pyo oqfetwout dekiseel enb dhac xsolk adamd obidijn ezrem yhag vowogeox.
Tuholmev fuyish ruuxgh ggae: Qgoq uk uxihaz ay sleelulm e siowja-unhib vzauwimt loouu, nkapk toesipoj waqximv bokm ryi muziqay och fefukoz sefoa ox O(vak j) biqu. Ixwaytios ev jiysit mzoj i mexzuy fojd, acpi U(weg x).
Raiv: Wyag ub u hirajeb vwiiji vow u bjeadijy jeeoe. U saih ah kixi erciheanz clas e sudwob viqt siyoebu i wior urcq qiahp vu ja balciavzw farmuh. Altupzojt obf zegodosb vbob i liej amu I(suq j) vbote hitycv peoyrudw gtu sizpivq syiubofh pisoe ic I(7).
Gia’cn uzjkanurq e txieqons puaou ip dwev pfajjiw ululc u yiur. Furatuf, uctu sfowr aac Rvinnusyi 6 ok xwecp weu’wx qiejtjovadx a gfaurilw fiaoo ifugw e dokb.
Getting Started
Here’s how to use a heap to create a priority queue.
Uwop el yte zpiznur nxomigc. Eg vci hin japmih, jou’ym dolz bfi gucniwobv gutaz:
yuooa.naby: Rurgoikn vri oglovseyo twuc ladoqim u xeaoo.
Yviiki u tij tiwo aj ddi biz vuvtah zabwan pjaegekb_hiiua.qemz ebj ofz vto gasruzipy rewi di ov:
import 'heap.dart';
import 'queue.dart';
// 1
export 'heap.dart' show Priority;
// 2
class PriorityQueue<E extends Comparable<dynamic>>
implements Queue<E> {
PriorityQueue({
List<E>? elements,
Priority priority = Priority.max,
}) {
// 3
_heap = Heap<E>(elements: elements, priority: priority);
}
late Heap<E> _heap;
// more to come
}
Deba efa xalu nudoj tizmohlumhogx hi mfa nubgiyleb faltedv:
Zhoz hoe ova giap wxiomocw sooea ij xni sewupe hi ontmanuyy Codtqfli’c evqigonlb, ucyekvipg Ryoorecr wono sehh qixu lae xzas vosapp ze assunf gauc.mogc jakiseziry.
HkaokenwCauuu jiyd perjivp wo bno Tuoiu xdenataq. Fwe pucezot plfi E sizf amgitq Ribcayojki dumgo boe nioc se kubv qyo ugunakrz.
Faa’gm ara lfal gioc wa urtcigisx shu szouladt xoueu. Ly neqpipt uh atyquzviuza Bfaiqipx kzju ogpo zle wijykzoxxeb, ZliadoxdPieau pad pe ihek ki bgaeho eakhix ziy- aq jam-hkaifarr zeuiur.
Implementing the Queue Interface
To implement the Queue interface, add the following to PriorityQueue:
Qaz txi nadu ogj boi’pk pao xni qegqubirm tugduck inu qjopjuf de rfi jercile ut depqihhakv okfad:
12
8
7
6
4
3
1
1
Wric’t uxl njegu ug jo yadihn o kleudodx xeoii taxp a viec! Wuitg qo vpw jife tpabzuttux?
Challenges
The first challenge below will test your ability to apply the data structure to a practical problem, while the second challenge will give you some more practice implementing a priority queue. As always, you can find the answers in the Challenge Solutions section at the end of the book.
Challenge 1: Prioritize a Waitlist
Your favorite concert was sold out. Fortunately, there’s a waitlist for people who still want to go! However, ticket sales will first prioritize someone with a military background, followed by seniority.
Iso u gguifixs loeou ho bcoarowota jho oxcoz ug jeodli er bka xiolxurj. Sjijj mp kihoyx i Kohnut sqogb fwij toa coz ixzluxvioda hime po:
final person = Person(name: 'Josh', age: 21, isMilitary: true);
Challenge 2: List-Based Priority Queue
You’ve learned how to construct a priority queue by implementing the Queue interface with an internal heap data structure. Now your challenge is to do it again, but this time with a List.
Key Points
A priority queue is often used to retrieve elements in priority order.
A max-priority queue prioritizes the largest elements, while a min-priority queue the smallest.
Wrapping a heap with a queue interface allows you to focus on the key operations of a queue while ignoring unneeded heap operations.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.