Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Priority queue
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
{{short description|Abstract data type in computer science}} In [[computer science]], a '''priority queue''' is an [[abstract data type]] similar to a regular [[queue (abstract data type)|queue]] or [[stack (abstract data type)|stack]] abstract data type. In a priority queue, each element has an associated ''priority'', which determines its order of service.<ref name=":0">{{Cite journal |last=Miller Jr. |first=Robert G. |date=1960 |title=Priority queues |url=https://projecteuclid.org/journals/annals-of-mathematical-statistics/volume-31/issue-1/Priority-Queues/10.1214/aoms/1177705990.pdf |journal=The Annals of Mathematical Statistics |volume=31 |pages=86β103 |publisher=Stanford University|doi=10.1214/aoms/1177705990 }}</ref> Priority queue serves highest priority items first.<ref name=":0" /> Priority values have to be instances of an ordered data type, and higher priority can be given either to the lesser or to the greater values with respect to the given order relation. For example, in [[Java (programming language)|Java]] standard library, ''PriorityQueue'''s the least elements with respect to the order have the highest priority.<ref>{{Cite web |title=PriorityQueue (Java SE 9 & JDK 9 ) |url=https://docs.oracle.com/javase/9/docs/api/java/util/PriorityQueue.html |access-date=2025-03-13 |website=docs.oracle.com}}</ref> This implementation detail is without much practical significance, since passing to the [[converse relation|opposite order relation]] turns the least values into the greatest, and vice versa. While priority queues are often implemented using [[Heap (data structure) |heaps]], they are conceptually distinct. A priority queue can be implemented with a heap or with other methods; just as a list can be implemented with a [[linked list]] or with an [[Array data structure|array]]. == Operations == A priority queue has the following operations:<ref>{{Introduction to Algorithms|edition=4|chapter=Chapter 6.5: Priority queues|pages=172β176}}</ref><ref name=":1">{{Cite journal |last1=RΓΆnngren |first1=Robert |last2=Ayani |first2=Rassul |date=1997-04-01 |title=A comparative study of parallel and sequential priority queue algorithms |url=https://dl.acm.org/doi/10.1145/249204.249205 |journal=ACM Trans. Model. Comput. Simul. |volume=7 |issue=2 |pages=157β209 |doi=10.1145/249204.249205 |issn=1049-3301}}</ref><ref name=":2">{{Cite book |last=Ayani |first=R. |chapter=LR-algorithm: Concurrent operations on priority queues |date=December 1990 |title=Proceedings of the Second IEEE Symposium on Parallel and Distributed Processing 1990 |chapter-url=https://ieeexplore.ieee.org/document/143500 |pages=22β25 |doi=10.1109/SPDP.1990.143500|isbn=0-8186-2087-0 }}</ref> {{div col|colwidth=20em}} === Max-priority queue === * ''insert(S, element, priority)'':<ref name=":1" /><ref name=":2" /> add an element to set ''S'' with an associated priority. * ''maximum(S)'': return the element with ''highest priority''. *: This is also known as "''find_max''". * ''extract_max(S)'': remove the element from set ''S'' with ''highest priority'', and return it. *: This is also known as "''delete''",<ref name=":1" /> or "''extract''".<ref name=":2" /> * ''increase_key(S, element, k)'': increase the associated priority with an element to the new value ''k''. === Min-priority queue === * ''insert(S, element, priority)'':<ref name=":1" /><ref name=":2" /> add an element to set ''S'' with an associated priority. * ''minimum(S)'': return the element with ''lowest priority''. *: This is also known as "''find_min''". * ''extract_min(S)'': remove the element from set ''S'' with ''lowest priority'', and return it. *: This is also known as "''delete''",<ref name=":1" /> or "''extract''".<ref name=":2" /> * ''decrease_key(S, element, k)'': decrease the associated priority with an element to the new value ''k''. {{div col end}} [[Stack (abstract data type)|Stacks]] and [[Queue (abstract data type)|queues]] can be implemented as particular kinds of priority queues, with the priority determined by the order in which the elements are inserted. In a stack, the priority of each inserted element is monotonically increasing; thus, the last element inserted is always the first retrieved. In a queue, the priority of each inserted element is monotonically decreasing; thus, the first element inserted is always the first retrieved. In some implementations, if two elements have the same priority, they are served in the same order in which they were enqueued. In other implementations, the order of elements with the same priority is undefined. == Implementation == === Naive implementations === One can create a simple, but inefficient priority queue in a number of ways. These naive implementations can demonstrate the expected behaviour of a priority queue in a simpler manner. * ''insert'' elements into an unsorted array; find and ''extract'' element with ''highest priority'' *: Performance: "''insert''" performs in O(1) constant time, where "''extract_max''" performs in O(n) linear time. '''insert'''(element, priority): node.element β element node.priority β priority list.append(node) '''extract_max'''(): highest β 0 foreach node in list: if highest.priority < node.priority: highest β node list.remove(highest) return highest.element * ''insert'' elements into a sorted array; ''extract'' first element *: Performance: "''insert''" performs in O(n) linear time, where "''extract_max''" performs in O(1) constant time. '''insert'''(element, priority): node.element β element node.priority β priority for i in [0...N]: element β list.get_at_index(i) if element.priority < node.priority: list.insert_at_index(node, i + 1) return '''extract_max'''(): highest β list.get_at_index(0) list.remove(highest) return highest.element === Usual implementation === To improve performance, priority queues are typically based on a [[Heap (data structure)|heap]], giving ''O''(log ''n'') performance for inserts and removals, and ''O''(''n'') to build the [[Heap (data structure)|heap]] initially from a set of ''n'' elements. Variants of the basic heap data structure such as [[pairing heap]]s or [[Fibonacci heap]]s can provide better bounds for some operations.<ref name="CLRS_priority_queue_pp476">{{Introduction to Algorithms|edition=2|chapter=Chapter 20: Fibonacci Heaps|pages=476β497}} Third edition, p. 518.</ref> Alternatively, when a [[self-balancing binary search tree]] is used, insertion and removal also take ''O''(log ''n'') time, although building trees from existing sequences of elements takes ''O''(''n'' log ''n'') time; this is typical where one might already have access to these data structures, such as with third-party or standard libraries. From a space-complexity standpoint, using [[self-balancing binary search tree]] with [[linked list]] takes more storage, since it requires to store extra references to other nodes. From a computational-complexity standpoint, priority queues are congruent to sorting algorithms. The section on [[#Equivalence of priority queues and sorting algorithms|the equivalence of priority queues and sorting algorithms]], below, describes how efficient sorting algorithms can create efficient priority queues. ===Specialized heaps=== There are several specialized [[heap (data structure)|heap]] [[data structures]] that either supply additional operations or outperform heap-based implementations for specific types of keys, specifically integer keys. Suppose the set of possible keys is {1, 2, ..., C}. * When only ''insert'', ''find-min'' and ''extract-min'' are needed and in case of integer priorities, a [[bucket queue]] can be constructed as an array of {{mvar|C}} [[linked list]]s plus a pointer {{math|top}}, initially {{mvar|C}}. Inserting an item with key {{mvar|k}} appends the item to the {{mvar|k}}'th list, and updates {{math|top β min(top, ''k'')}}, both in constant time. ''Extract-min'' deletes and returns one item from the list with index {{math|top}}, then increments {{math|top}} if needed until it again points to a non-empty list; this takes {{math|''O''(''C'')}} time in the worst case. These queues are useful for sorting the vertices of a graph by their degree.<ref>{{cite book |last=Skiena |first=Steven |author-link=Steven Skiena |title = The Algorithm Design Manual |publisher=[[Springer Science+Business Media]] |edition=2nd |year = 2010 |isbn=978-1-849-96720-4}}</ref>{{rp|374}} * A [[van Emde Boas tree]] supports the ''minimum'', ''maximum'', ''insert'', ''delete'', ''search'', ''extract-min'', ''extract-max'', ''predecessor'' and ''successor]'' operations in ''O''(log log ''C'') time, but has a space cost for small queues of about ''O''(2<sup>''m''/2</sup>), where ''m'' is the number of bits in the priority value.<ref>P. van Emde Boas. Preserving order in a forest in less than logarithmic time. In ''Proceedings of the 16th Annual Symposium on Foundations of Computer Science'', pages 75-84. IEEE Computer Society, 1975.</ref> The space can be reduced significantly with hashing. * The [[Fusion tree]] by [[Michael Fredman|Fredman]] and [[Dan Willard|Willard]] implements the ''minimum'' operation in ''O''(1) time and ''insert'' and ''extract-min'' operations in <math>O(\log n / \log \log C)</math>time. However it is stated by the author that, "Our algorithms have theoretical interest only; The constant factors involved in the execution times preclude practicality."<ref>[[Michael Fredman|Michael L. Fredman]] and Dan E. Willard. Surpassing the information theoretic bound with fusion trees. ''Journal of Computer and System Sciences'', 48(3):533-551, 1994</ref> For applications that do many "[[Peek (data type operation)|peek]]" operations for every "extract-min" operation, the time complexity for peek actions can be reduced to ''O''(1) in all tree and heap implementations by caching the highest priority element after every insertion and removal. For insertion, this adds at most a constant cost, since the newly inserted element is compared only to the previously cached minimum element. For deletion, this at most adds an additional "peek" cost, which is typically cheaper than the deletion cost, so overall time complexity is not significantly impacted. [[Monotone priority queue]]s are specialized queues that are optimized for the case where no item is ever inserted that has a lower priority (in the case of min-heap) than any item previously extracted. This restriction is met by several practical applications of priority queues. ===Summary of running times=== {{Heap Running Times}} == Equivalence of priority queues and sorting algorithms == === Using a priority queue to sort === The [[operational semantics|semantics]] of priority queues naturally suggest a sorting method: insert all the elements to be sorted into a priority queue, and sequentially remove them; they will come out in sorted order. This is actually the procedure used by several [[sorting algorithm]]s, once the layer of [[abstraction (computer science)|abstraction]] provided by the priority queue is removed. This sorting method is equivalent to the following sorting algorithms: {|class="wikitable sortable" ! Name !! Priority Queue Implementation !! Best !! Average !! Worst |- align="center" | [[Heapsort]] | [[Heap (data structure)|Heap]] |style="background:#dfd"|''n'' log ''n'' |style="background:#dfd"|''n'' log ''n'' |style="background:#dfd"|''n'' log ''n'' |- align="center" | [[Smoothsort]] | Leonardo Heap |style="background:#dfd"|''n'' |style="background:#dfd"|''n'' log ''n'' |style="background:#dfd"|''n'' log ''n'' |- align="center" | [[Selection sort]] | Unordered [[Array#In computer science|Array]] |style="background:#fdd"|''n<sup>2</sup>'' |style="background:#fdd"|''n<sup>2</sup>'' |style="background:#fdd"|''n<sup>2</sup>'' |- align="center" | [[Insertion sort]] | Ordered [[Array#In computer science|Array]] |style="background:#dfd"|''n'' |style="background:#fdd"|''n<sup>2</sup>'' |style="background:#fdd"|''n<sup>2</sup>'' |- align="center" | [[Tree sort]] | [[Self-balancing binary search tree]] |style="background:#dfd"|''n'' log ''n'' |style="background:#dfd"|''n'' log ''n'' |style="background:#dfd"|''n'' log ''n'' |} === Using a sorting algorithm to make a priority queue === A sorting algorithm can also be used to implement a priority queue. Specifically, Thorup says:<ref>{{Cite journal | last1 = Thorup | first1 = Mikkel | author-link1 = Mikkel Thorup | year = 2007 | title = Equivalence between priority queues and sorting | journal = [[Journal of the ACM]] | volume = 54 | issue = 6 | page = 28 | doi = 10.1145/1314690.1314692 | s2cid = 11494634 }}</ref> <blockquote> We present a general deterministic linear space reduction from priority queues to sorting implying that if we can sort up to ''n'' keys in ''S''(''n'') time per key, then there is a priority queue supporting ''delete'' and ''insert'' in ''O''(''S''(''n'')) time and ''find-min'' in constant time. </blockquote> That is, if there is a sorting algorithm which can sort in ''O''(''S'') time per key, where ''S'' is some function of ''n'' and [[word size]],<ref>{{cite web |url=http://courses.csail.mit.edu/6.851/spring07/scribe/lec17.pdf |title=Archived copy |access-date=2011-02-10 |url-status=live |archive-url=https://web.archive.org/web/20110720000413/http://courses.csail.mit.edu/6.851/spring07/scribe/lec17.pdf |archive-date=2011-07-20 }}</ref> then one can use the given procedure to create a priority queue where pulling the highest-priority element is ''O''(1) time, and inserting new elements (and deleting elements) is ''O''(''S'') time. For example, if one has an ''O''(''n'' log ''n'') sort algorithm, one can create a priority queue with ''O''(1) pulling and ''O''( log ''n'') insertion. == Libraries == A priority queue is often considered to be a "[[container (abstract data type)|container data structure]]". The [[Standard Template Library]] (STL), and the [[C++]] 1998 standard, specifies [https://en.cppreference.com/w/cpp/container/priority_queue std::priority_queue] as one of the STL [[container (programming)|container]] [[adaptor (programming)|adaptor]] [[Template (programming)|class template]]s. However, it does not specify how two elements with same priority should be served, and indeed, common implementations will not return them according to their order in the queue. It implements a max-priority-queue, and has three parameters: a comparison object for sorting such as a function object (defaults to less<T> if unspecified), the underlying container for storing the data structures (defaults to std::vector<T>), and two iterators to the beginning and end of a sequence. Unlike actual STL containers, it does not allow [[Iterator|iteration]] of its elements (it strictly adheres to its abstract data type definition). STL also has utility functions for manipulating another random-access container as a binary max-heap. The [[Boost (C++ libraries)|Boost libraries]] also have an implementation in the library heap. Python's [https://docs.python.org/library/heapq.html heapq] module implements a binary min-heap on top of a list. [[Java (programming language)|Java]]'s library contains a {{Javadoc:SE|java/util|PriorityQueue}} class, which implements a min-priority-queue as a binary heap. [[.NET]]'s library contains a [https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.priorityqueue-2?view=net-6.0 PriorityQueue] class, which implements an array-backed, quaternary min-heap. [[Scala (programming language)|Scala]]'s library contains a [https://www.scala-lang.org/api/current/scala/collection/mutable/PriorityQueue.html PriorityQueue] class, which implements a max-priority-queue. [[Go (programming language)|Go]]'s library contains a [http://golang.org/pkg/container/heap/ container/heap] module, which implements a min-heap on top of any compatible data structure. The [[Standard PHP Library]] extension contains the class [http://us2.php.net/manual/en/class.splpriorityqueue.php SplPriorityQueue]. Apple's [[Core Foundation]] framework contains a [https://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFBinaryHeapRef/Reference/reference.html CFBinaryHeap] structure, which implements a min-heap. == Applications == === Bandwidth management === Priority queuing can be used to manage limited resources such as [[Bandwidth (computing)|bandwidth]] on a transmission line from a [[computer network|network]] [[router (computing)|router]]. In the event of outgoing [[traffic]] queuing due to insufficient bandwidth, all other queues can be halted to send the traffic from the highest priority queue upon arrival. This ensures that the prioritized traffic (such as real-time traffic, e.g. an [[Real-time Transport Protocol|RTP]] stream of a [[Voice over Internet Protocol|VoIP]] connection) is forwarded with the least delay and the least likelihood of being rejected due to a queue reaching its maximum capacity. All other traffic can be handled when the highest priority queue is empty. Another approach used is to send disproportionately more traffic from higher priority queues. Many modern protocols for [[local area network]]s also include the concept of priority queues at the [[media access control]] (MAC) sub-layer to ensure that high-priority applications (such as [[VoIP]] or [[IPTV]]) experience lower latency than other applications which can be served with [[best-effort service]]. Examples include [[IEEE 802.11e]] (an amendment to [[IEEE 802.11]] which provides [[quality of service]]) and [[ITU-T]] [[G.hn]] (a standard for high-speed [[local area network]] using existing home wiring ([[Power line communication|power lines]], phone lines and [[Ethernet over coax|coaxial cables]]). Usually a limitation (policer) is set to limit the bandwidth that traffic from the highest priority queue can take, in order to prevent high priority packets from choking off all other traffic. This limit is usually never reached due to high level control instances such as the [[Cisco Systems, Inc.|Cisco]] [[Callmanager]], which can be programmed to inhibit calls which would exceed the programmed bandwidth limit. <!-- this was marked IMHO in the original Priority queues exist on ISO-layer 2 (which is Ethernet or WAN interfaces such as T1 / E1) and are filled by entry-criterions such as [[Diffserv]] Codepoints or IP-Precedence. Network equipment usually can be programmed to pick up priority packets by the layer 4 info (IP protocol and port) or the new one by a mechanism called [[NBAR]]. --> === Discrete event simulation === Another use of a priority queue is to manage the events in a [[discrete event simulation]]. The events are added to the queue with their simulation time used as the priority. The execution of the simulation proceeds by repeatedly pulling the top of the queue and executing the event thereon. ''See also'': [[Scheduling (computing)]], [[queueing theory]] === Dijkstra's algorithm === When the graph is stored in the form of [[adjacency list]] or matrix, priority queue can be used to extract minimum efficiently when implementing [[Dijkstra's algorithm]], although one also needs the ability to alter the priority of a particular vertex in the priority queue efficiently. If instead, a graph is stored as node objects, and priority-node pairs are inserted into a heap, altering the priority of a particular vertex is not necessary if one tracks visited nodes. Once a node is visited, if it comes up in the heap again (having had a lower priority number associated with it earlier), it is popped-off and ignored. === Huffman coding === [[Huffman coding]] requires one to repeatedly obtain the two lowest-frequency trees. A priority queue is [[Huffman coding#Compression|one method of doing this]]. === Best-first search algorithms === [[Best-first search]] algorithms, like the [[A* search algorithm]], find the shortest path between two [[vertex (graph theory)|vertices]] or [[Node (graph theory)|nodes]] of a [[weighted graph]], trying out the most promising routes first. A priority queue (also known as the ''fringe'') is used to keep track of unexplored routes; the one for which the estimate (a lower bound in the case of A*) of the total path length is smallest is given highest priority. If memory limitations make best-first search impractical, variants like the [[SMA*]] algorithm can be used instead, with a [[double-ended priority queue]] to allow removal of low-priority items. === ROAM triangulation algorithm === The Real-time Optimally Adapting Meshes ([[ROAM]]) algorithm computes a dynamically changing triangulation of a terrain. It works by splitting triangles where more detail is needed and merging them where less detail is needed. The algorithm assigns each triangle in the terrain a priority, usually related to the error decrease if that triangle would be split. The algorithm uses two priority queues, one for triangles that can be split and another for triangles that can be merged. In each step the triangle from the split queue with the highest priority is split, or the triangle from the merge queue with the lowest priority is merged with its neighbours. === Prim's algorithm for minimum spanning tree === Using [[Binary heap|min heap priority queue]] in [[Prim's algorithm]] to find the [[minimum spanning tree]] of a [[Connected graph|connected]] and [[undirected graph]], one can achieve a good running time. This min heap priority queue uses the min heap data structure which supports operations such as ''insert'', ''minimum'', ''extract-min'', ''decrease-key''.<ref name="CLR">{{Introduction to Algorithms |edition=3 |pages=634}} "In order to implement Prim's algorithm efficiently, we need a fast way to select a new edge to add to the tree formed by the edges in A."</ref> In this implementation, the [[weighted graph|weight]] of the edges is used to decide the priority of the [[Vertex (graph theory)|vertices]]. Lower the weight, higher the priority and higher the weight, lower the priority.<ref name="GEEKS"> {{cite web |url = http://www.geeksforgeeks.org/greedy-algorithms-set-5-prims-minimum-spanning-tree-mst-2/ |title = Prim's Algorithm |date = 18 November 2012 |publisher = Geek for Geeks |access-date = 12 September 2014 |url-status = live |archive-url = https://web.archive.org/web/20140909020508/http://www.geeksforgeeks.org/greedy-algorithms-set-5-prims-minimum-spanning-tree-mst-2/ |archive-date = 9 September 2014 }} </ref> == Parallel priority queue == Parallelization can be used to speed up priority queues, but requires some changes to the priority queue interface. The reason for such changes is that a sequential update usually only has <math display="inline">O(1)</math> or <math display="inline">O(\log n)</math> cost, and there is no practical gain to parallelize such an operation. One possible change is to allow the concurrent access of multiple processors to the same priority queue. The second possible change is to allow batch operations that work on <math display="inline">k</math> elements, instead of just one element. For example, ''extractMin'' will remove the first <math display="inline">k</math> elements with the highest priority. === Concurrent parallel access === If the priority queue allows concurrent access, multiple processes can perform operations concurrently on that priority queue. However, this raises two issues. First of all, the definition of the semantics of the individual operations is no longer obvious. For example, if two processes want to extract the element with the highest priority, should they get the same element or different ones? This restricts parallelism on the level of the program using the priority queue. In addition, because multiple processes have access to the same element, this leads to contention. [[File:concurrent_prio_queue_conflict.svg|thumb|Node 3 is inserted and sets the pointer of node 2 to node 3. Immediately after that, node 2 is deleted and the pointer of node 1 is set to node 4. Now node 3 is no longer reachable.]] The concurrent access to a priority queue can be implemented on a Concurrent Read, Concurrent Write (CRCW) PRAM model. In the following the priority queue is implemented as a [[skip list]].<ref name = skiplist>{{cite journal |last1= Sundell |first1=HΓ₯kan |last2= Tsigas |first2= Philippas |date=2005 |title=Fast and lock-free concurrent priority queues for multi-thread systems |url= https://doi.org/10.1016/j.jpdc.2004.12.005 |journal= Journal of Parallel and Distributed Computing |volume= 65 |issue= 5 |pages= 609β627 |doi= 10.1109/IPDPS.2003.1213189|s2cid=20995116 |citeseerx= 10.1.1.67.1310 }}</ref><ref>{{citation|surname1=LindΓ©n, Jonsson|periodical=Technical Report 2018-003|title=A Skiplist-Based Concurrent Priority Queue with Minimal Memory Contention|date=2013|language=de|url=http://www.it.uu.se/research/publications/reports/2018-003/ }}</ref> In addition, an atomic synchronization primitive, [[Compare-and-swap|CAS]], is used to make the skip list [[Lock (computer science)|lock]]-free. The nodes of the skip list consists of a unique key, a priority, an [[array data structure|array]] of [[Pointer (computer programming)|pointers]], for each level, to the next nodes and a ''delete'' mark. The ''delete'' mark marks if the node is about to be deleted by a process. This ensures that other processes can react to the deletion appropriately. *''insert(e)'': First, a new node with a key and a priority is created. In addition, the node is assigned a number of levels, which dictates the size of the array of pointers. Then a search is performed to find the correct position where to insert the new node. The search starts from the first node and from the highest level. Then the skip list is traversed down to the lowest level until the correct position is found. During the search, for every level the last traversed node will be saved as parent node for the new node at that level. In addition, the node to which the pointer, at that level, of the parent node points towards, will be saved as the successor node of the new node at that level. Afterwards, for every level of the new node, the pointers of the parent node will be set to the new node. Finally, the pointers, for every level, of the new node will be set to the corresponding successor nodes. *''extract-min'': First, the skip list is traversed until a node is reached whose ''delete'' mark is not set. This ''delete'' mark is than set to true for that node. Finally the pointers of the parent nodes of the deleted node are updated. If the concurrent access to a priority queue is allowed, conflicts may arise between two processes. For example, a conflict arises if one process is trying to insert a new node, but at the same time another process is about to delete the predecessor of that node.<ref name = skiplist/> There is a risk that the new node is added to the skip list, yet it is not longer reachable. ([[:File:concurrent_prio_queue_conflict.svg|See image]]) === ''K''-element operations === In this setting, operations on a priority queue is generalized to a batch of <math display="inline">k</math> elements. For instance, ''k_extract-min'' deletes the <math display="inline">k</math> smallest elements of the priority queue and returns those. In a [[Parallel programming model|shared-memory setting]], the parallel priority queue can be easily implemented using parallel [[binary search trees]] and [[join-based tree algorithms]]. In particular, ''k_extract-min'' corresponds to a ''split'' on the binary search tree that has <math display="inline">O(\log n)</math> cost and yields a tree that contains the <math display="inline">k</math> smallest elements. ''k_insert'' can be applied by a ''union'' of the original priority queue and the batch of insertions. If the batch is already sorted by the key, ''k_insert'' has <math display="inline">O(k\log (1+\frac{n}{k}))</math> cost. Otherwise, we need to first sort the batch, so the cost will be <math display="inline">O(k\log (1+\frac{n}{k})+k\log k)=O(k\log n)</math>. Other operations for priority queue can be applied similarly. For instance, ''k_decrease-key'' can be done by first applying ''difference'' and then ''union'', which first deletes the elements and then inserts them back with the updated keys. All these operations are highly parallel, and the theoretical and practical efficiency can be found in related research papers.<ref name="join-based">{{citation | last1 = Blelloch | first1 = Guy E. | last2 = Ferizovic | first2 = Daniel | last3 = Sun | first3 = Yihan | contribution = Just Join for Parallel Ordered Sets | doi = 10.1145/2935764.2935768 | isbn = 978-1-4503-4210-0 | pages = 253β264 | publisher = ACM | title = Symposium on Parallel Algorithms and Architectures, Proc. of 28th ACM Symp. Parallel Algorithms and Architectures (SPAA 2016) | year = 2016 | arxiv = 1602.02120 | s2cid = 2897793 }}</ref><ref name="pam">{{citation | last1 = Blelloch | first1 = Guy E. | last2 = Ferizovic | first2 = Daniel | last3 = Sun | first3 = Yihan | contribution = PAM: parallel augmented maps | pages = 290β304 | title = Proceedings of the 23rd ACM SIGPLAN Symposium on Principles and Practice of Parallel Programming | publisher = ACM | year = 2018}}</ref> The rest of this section discusses a queue-based algorithm on distributed memory. We assume each processor has its own local memory and a local (sequential) priority queue. The elements of the global (parallel) priority queue are distributed across all processors. [[File:BulkDeletionPQ.svg|thumb|''k_extract-min'' is executed on a priority queue with three processors. The green elements are returned and removed from the priority queue.]] A ''k_insert'' operation assigns the elements uniformly random to the processors which insert the elements into their local queues. Note that single elements can still be inserted into the queue. Using this strategy the global smallest elements are in the union of the local smallest elements of every processor with high probability. Thus each processor holds a representative part of the global priority queue. This property is used when ''k_extract-min'' is executed, as the smallest <math display="inline">m</math> elements of each local queue are removed and collected in a result set. The elements in the result set are still associated with their original processor. The number of elements <math display="inline">m</math> that is removed from each local queue depends on <math display="inline">k</math> and the number of processors <math display="inline">p</math>. <ref name=AlgToolbox>{{cite book | first1=Peter | last1=Sanders | first2=Kurt | last2=Mehlhorn | first3=Martin | last3=Dietzfelbinger | first4=Roman | last4= Dementiev | title=Sequential and Parallel Algorithms and Data Structures - The Basic Toolbox | publisher=Springer International Publishing | date=2019 | pages=226β229 | doi=10.1007/978-3-030-25209-0| isbn=978-3-030-25208-3 | s2cid=201692657 }}</ref> By parallel selection the <math display="inline">k</math> smallest elements of the result set are determined. With high probability these are the global <math display="inline">k</math> smallest elements. If not, <math display="inline">m</math> elements are again removed from each local queue and put into the result set. This is done until the global <math display="inline">k</math> smallest elements are in the result set. Now these <math display="inline">k</math> elements can be returned. All other elements of the result set are inserted back into their local queues. The running time of ''k_extract-min'' is expected <math display="inline"> O(\frac{k}{p} \log(n)) </math>, where <math display="inline">k = \Omega(p \cdot \log (p))</math> and <math display="inline">n</math> is the size of the priority queue.<ref name="AlgToolbox"/> The priority queue can be further improved by not moving the remaining elements of the result set directly back into the local queues after a ''k_extract-min'' operation. This saves moving elements back and forth all the time between the result set and the local queues. By removing several elements at once a considerable speedup can be reached. But not all algorithms can use this kind of priority queue. Dijkstra's algorithm for example can not work on several nodes at once. The algorithm takes the node with the smallest distance from the priority queue and calculates new distances for all its neighbor nodes. If you would take out <math display="inline">k</math> nodes, working at one node could change the distance of another one of the <math display="inline">k</math> nodes. So using k-element operations destroys the label setting property of Dijkstra's algorithm. == See also == * [[Batch queue]] * [[Command queue]] * [[Job scheduler]] == References == {{Reflist}} == Further reading == *{{Introduction to Algorithms|edition=2|chapter=Section 6.5: Priority queues|pages=138β142}} == External links == * [http://en.cppreference.com/w/cpp/container/priority_queue C++ reference for <code>std::priority_queue</code>] * [http://leekillough.com/heaps/ Descriptions] by [[Lee Killough (programmer)|Lee Killough]] * [https://github.com/vy/libpqueue libpqueue] is a generic priority queue (heap) implementation (in C) used by the Apache HTTP Server project. * [https://web.archive.org/web/20121103132051/http://www.theturingmachine.com/algorithms/heaps.html Survey of known priority queue structures] by Stefan Xenos * [https://archive.org/details/ucberkeley_webcast_yIUFT6AKBGE UC Berkeley - Computer Science 61B - Lecture 24: Priority Queues] (video) - introduction to priority queues using binary heap {{Data structures}} [[Category:Priority queues| ]] [[Category:Abstract data types]]
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)
Pages transcluded onto the current version of this page
(
help
)
:
Template:Citation
(
edit
)
Template:Cite book
(
edit
)
Template:Cite journal
(
edit
)
Template:Cite web
(
edit
)
Template:Data structures
(
edit
)
Template:Div col
(
edit
)
Template:Div col end
(
edit
)
Template:Heap Running Times
(
edit
)
Template:Introduction to Algorithms
(
edit
)
Template:Javadoc:SE
(
edit
)
Template:Math
(
edit
)
Template:Mvar
(
edit
)
Template:Reflist
(
edit
)
Template:Rp
(
edit
)
Template:Short description
(
edit
)