Priority queue: Difference between revisions

Content added Content deleted
m (Priority Qutue page fix highlighting...)
m (syntax highlighting fixup automation)
Line 33: Line 33:
{{trans|Python}}
{{trans|Python}}


<syntaxhighlight lang=11l>V items = [(3, ‘Clear drains’), (4, ‘Feed cat’), (5, ‘Make tea’), (1, ‘Solve RC tasks’), (2, ‘Tax return’)]
<syntaxhighlight lang="11l">V items = [(3, ‘Clear drains’), (4, ‘Feed cat’), (5, ‘Make tea’), (1, ‘Solve RC tasks’), (2, ‘Tax return’)]
minheap:heapify(&items)
minheap:heapify(&items)
L !items.empty
L !items.empty
Line 49: Line 49:
=={{header|AArch64 Assembly}}==
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
<syntaxhighlight lang=AArch64 Assembly>
<syntaxhighlight lang="aarch64 assembly">
/* ARM assembly AARCH64 Raspberry PI 3B */
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program priorQueue64.s */
/* program priorQueue64.s */
Line 436: Line 436:
The user must type in the monitor the following command after compilation and before running the program!<pre>SET EndProg=*</pre>
The user must type in the monitor the following command after compilation and before running the program!<pre>SET EndProg=*</pre>
{{libheader|Action! Tool Kit}}
{{libheader|Action! Tool Kit}}
<syntaxhighlight lang=Action!>CARD EndProg ;required for ALLOCATE.ACT
<syntaxhighlight lang="action!">CARD EndProg ;required for ALLOCATE.ACT


INCLUDE "D2:ALLOCATE.ACT" ;from the Action! Tool Kit. You must type 'SET EndProg=*' from the monitor after compiling, but before running this program!
INCLUDE "D2:ALLOCATE.ACT" ;from the Action! Tool Kit. You must type 'SET EndProg=*' from the monitor after compiling, but before running this program!
Line 564: Line 564:
Ada 2012 includes container classes for priority queues.
Ada 2012 includes container classes for priority queues.


<syntaxhighlight lang=Ada>with Ada.Containers.Synchronized_Queue_Interfaces;
<syntaxhighlight lang="ada">with Ada.Containers.Synchronized_Queue_Interfaces;
with Ada.Containers.Unbounded_Priority_Queues;
with Ada.Containers.Unbounded_Priority_Queues;
with Ada.Strings.Unbounded;
with Ada.Strings.Unbounded;
Line 612: Line 612:
=={{header|ARM Assembly}}==
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang=ARM Assembly>
<syntaxhighlight lang="arm assembly">
/* ARM assembly Raspberry PI */
/* ARM assembly Raspberry PI */
/* program priorqueue.s */
/* program priorqueue.s */
Line 1,050: Line 1,050:


=={{header|AutoHotkey}}==
=={{header|AutoHotkey}}==
<syntaxhighlight lang=AutoHotkey>;-----------------------------------
<syntaxhighlight lang="autohotkey">;-----------------------------------
PQ_TopItem(Queue,Task:=""){ ; remove and return top priority item
PQ_TopItem(Queue,Task:=""){ ; remove and return top priority item
TopPriority := PQ_TopPriority(Queue)
TopPriority := PQ_TopPriority(Queue)
Line 1,110: Line 1,110:
return, TopPriority
return, TopPriority
}</syntaxhighlight>
}</syntaxhighlight>
Examples:<syntaxhighlight lang=AutoHotkey>data =
Examples:<syntaxhighlight lang="autohotkey">data =
(
(
3 Clear drains
3 Clear drains
Line 1,136: Line 1,136:
Axiom already has a heap domain for ordered sets.
Axiom already has a heap domain for ordered sets.
We define a domain for ordered key-entry pairs and then define a priority queue using the heap domain over the pairs:
We define a domain for ordered key-entry pairs and then define a priority queue using the heap domain over the pairs:
<syntaxhighlight lang=Axiom>)abbrev Domain ORDKE OrderedKeyEntry
<syntaxhighlight lang="axiom">)abbrev Domain ORDKE OrderedKeyEntry
OrderedKeyEntry(Key:OrderedSet,Entry:SetCategory): Exports == Implementation where
OrderedKeyEntry(Key:OrderedSet,Entry:SetCategory): Exports == Implementation where
Exports == OrderedSet with
Exports == OrderedSet with
Line 1,162: Line 1,162:
setelt(x:%,key:Key,entry:Entry) ==
setelt(x:%,key:Key,entry:Entry) ==
insert!(construct(key,entry)$S,x)
insert!(construct(key,entry)$S,x)
entry</syntaxhighlight>For an example:<syntaxhighlight lang=Axiom>pq := empty()$PriorityQueue(Integer,String)
entry</syntaxhighlight>For an example:<syntaxhighlight lang="axiom">pq := empty()$PriorityQueue(Integer,String)
pq(3):="Clear drains";
pq(3):="Clear drains";
pq(4):="Feed cat";
pq(4):="Feed cat";
Line 1,177: Line 1,177:
=={{header|Batch File}}==
=={{header|Batch File}}==
Batch has only a data structure, the environment that incidentally sorts itself automatically by key. The environment has a limit of 64K
Batch has only a data structure, the environment that incidentally sorts itself automatically by key. The environment has a limit of 64K
<syntaxhighlight lang=Batch File>
<syntaxhighlight lang="batch file">
@echo off
@echo off
setlocal enabledelayedexpansion
setlocal enabledelayedexpansion
Line 1,218: Line 1,218:
=={{header|C}}==
=={{header|C}}==
Using a dynamic array as a binary heap. Stores integer priority and a character pointer. Supports push and pop.
Using a dynamic array as a binary heap. Stores integer priority and a character pointer. Supports push and pop.
<syntaxhighlight lang=c>#include <stdio.h>
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>


Line 1,298: Line 1,298:
=== Pairing heap w/ generic data types ===
=== Pairing heap w/ generic data types ===
header file:
header file:
<syntaxhighlight lang=C>
<syntaxhighlight lang="c">
typedef struct _pq_node_t {
typedef struct _pq_node_t {
long int key;
long int key;
Line 1,319: Line 1,319:
</syntaxhighlight>
</syntaxhighlight>
implementation:
implementation:
<syntaxhighlight lang=C>
<syntaxhighlight lang="c">
#include <stdlib.h>
#include <stdlib.h>
#include "pairheap.h"
#include "pairheap.h"
Line 1,362: Line 1,362:
</syntaxhighlight>
</syntaxhighlight>
usage:
usage:
<syntaxhighlight lang=C>
<syntaxhighlight lang="c">
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string.h>
Line 1,412: Line 1,412:


===.NET 6 solution===
===.NET 6 solution===
<syntaxhighlight lang=csharp>using System;
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Collections.Generic;


Line 1,447: Line 1,447:


===Pre-.NET 6 solution===
===Pre-.NET 6 solution===
<syntaxhighlight lang=csharp>using System;
<syntaxhighlight lang="csharp">using System;


namespace PriorityQueue
namespace PriorityQueue
Line 1,512: Line 1,512:
{{works with|C sharp|C#|3.0+/DotNet 3.5+}}
{{works with|C sharp|C#|3.0+/DotNet 3.5+}}
The above code is not really a true Priority Queue as it does not allow duplicate keys; also, the SortedList on which it is based does not have O(log n) insertions and removals for random data as a true Priority Queue does. The below code implements a true Min Heap Priority Queue:
The above code is not really a true Priority Queue as it does not allow duplicate keys; also, the SortedList on which it is based does not have O(log n) insertions and removals for random data as a true Priority Queue does. The below code implements a true Min Heap Priority Queue:
<syntaxhighlight lang=csharp>namespace PriorityQ {
<syntaxhighlight lang="csharp">namespace PriorityQ {
using KeyT = UInt32;
using KeyT = UInt32;
using System;
using System;
Line 1,654: Line 1,654:


The above code can be tested as per the page specification by the following code:
The above code can be tested as per the page specification by the following code:
<syntaxhighlight lang=csharp> static void Main(string[] args) {
<syntaxhighlight lang="csharp"> static void Main(string[] args) {
Tuple<uint, string>[] ins = { new Tuple<uint,string>(3u, "Clear drains"),
Tuple<uint, string>[] ins = { new Tuple<uint,string>(3u, "Clear drains"),
new Tuple<uint,string>(4u, "Feed cat"),
new Tuple<uint,string>(4u, "Feed cat"),
Line 1,714: Line 1,714:
The C++ standard library contains the <code>std::priority_queue</code> opaque data structure. It implements a max-heap.
The C++ standard library contains the <code>std::priority_queue</code> opaque data structure. It implements a max-heap.


<syntaxhighlight lang=cpp>#include <iostream>
<syntaxhighlight lang="cpp">#include <iostream>
#include <string>
#include <string>
#include <queue>
#include <queue>
Line 1,747: Line 1,747:
and use the heap operations to manipulate it:
and use the heap operations to manipulate it:


<syntaxhighlight lang=cpp>#include <iostream>
<syntaxhighlight lang="cpp">#include <iostream>
#include <string>
#include <string>
#include <vector>
#include <vector>
Line 1,789: Line 1,789:
=={{header|Clojure}}==
=={{header|Clojure}}==


<syntaxhighlight lang=clojure>user=> (use 'clojure.data.priority-map)
<syntaxhighlight lang="clojure">user=> (use 'clojure.data.priority-map)


; priority-map can be used as a priority queue
; priority-map can be used as a priority queue
Line 1,817: Line 1,817:
must support the less-than operator.
must support the less-than operator.


<syntaxhighlight lang=clu>prio_queue = cluster [P, T: type] is new, empty, push, pop
<syntaxhighlight lang="clu">prio_queue = cluster [P, T: type] is new, empty, push, pop
where P has lt: proctype (P,P) returns (bool)
where P has lt: proctype (P,P) returns (bool)
Line 1,920: Line 1,920:


=={{header|CoffeeScript}}==
=={{header|CoffeeScript}}==
<syntaxhighlight lang=coffeescript>
<syntaxhighlight lang="coffeescript">
PriorityQueue = ->
PriorityQueue = ->
# Use closure style for object creation (so no "new" required).
# Use closure style for object creation (so no "new" required).
Line 2,003: Line 2,003:
output
output


<lang>
<syntaxhighlight lang="text">
> coffee priority_queue.coffee
> coffee priority_queue.coffee
Solve RC tasks
Solve RC tasks
Line 2,016: Line 2,016:
=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
In this task were implemented to versions of the functions, the non-destructive ones that will not change the state of the priority queue and the destructive ones that will change. The destructive ones work very similarly to the 'pop' and 'push' functions.
In this task were implemented to versions of the functions, the non-destructive ones that will not change the state of the priority queue and the destructive ones that will change. The destructive ones work very similarly to the 'pop' and 'push' functions.
<syntaxhighlight lang=lisp>
<syntaxhighlight lang="lisp">
;priority-queue's are implemented with association lists
;priority-queue's are implemented with association lists
(defun make-pq (alist)
(defun make-pq (alist)
Line 2,062: Line 2,062:
=={{header|Component Pascal}}==
=={{header|Component Pascal}}==
BlackBox Component Builder
BlackBox Component Builder
<syntaxhighlight lang=oberon2>
<syntaxhighlight lang="oberon2">
MODULE PQueues;
MODULE PQueues;
IMPORT StdLog,Boxes;
IMPORT StdLog,Boxes;
Line 2,153: Line 2,153:
</syntaxhighlight>
</syntaxhighlight>
Interface extracted from the implementation
Interface extracted from the implementation
<syntaxhighlight lang=oberon2>
<syntaxhighlight lang="oberon2">
DEFINITION PQueues;
DEFINITION PQueues;


Line 2,188: Line 2,188:


=={{header|D}}==
=={{header|D}}==
<syntaxhighlight lang=d>import std.stdio, std.container, std.array, std.typecons;
<syntaxhighlight lang="d">import std.stdio, std.container, std.array, std.typecons;


void main() {
void main() {
Line 2,213: Line 2,213:
{{libheader| Boost.Generics.Collection}}
{{libheader| Boost.Generics.Collection}}
Boost.Generics.Collection is part of [https://github.com/MaiconSoft/DelphiBoostLib DelphiBoostLib]
Boost.Generics.Collection is part of [https://github.com/MaiconSoft/DelphiBoostLib DelphiBoostLib]
<syntaxhighlight lang=Delphi>program Priority_queue;
<syntaxhighlight lang="delphi">program Priority_queue;


{$APPTYPE CONSOLE}
{$APPTYPE CONSOLE}
Line 2,240: Line 2,240:
=={{header|EchoLisp}}==
=={{header|EchoLisp}}==
We use the built-in binary tree library. Each tree node has a datum (key . value). The functions (bin-tree-pop-first tree) and (bin-tree-pop-last tree) allow to extract the node with highest or lowest priority.
We use the built-in binary tree library. Each tree node has a datum (key . value). The functions (bin-tree-pop-first tree) and (bin-tree-pop-last tree) allow to extract the node with highest or lowest priority.
<syntaxhighlight lang=lisp>
<syntaxhighlight lang="lisp">
(lib 'tree)
(lib 'tree)
(define tasks (make-bin-tree 3 "Clear drains"))
(define tasks (make-bin-tree 3 "Clear drains"))
Line 2,263: Line 2,263:
=={{header|Elixir}}==
=={{header|Elixir}}==
{{trans|Erlang}}
{{trans|Erlang}}
<syntaxhighlight lang=elixir>defmodule Priority do
<syntaxhighlight lang="elixir">defmodule Priority do
def create, do: :gb_trees.empty
def create, do: :gb_trees.empty
Line 2,306: Line 2,306:
=={{header|Erlang}}==
=={{header|Erlang}}==
Using built in gb_trees module, with the suggested interface for this task.
Using built in gb_trees module, with the suggested interface for this task.
<syntaxhighlight lang=Erlang>
<syntaxhighlight lang="erlang">
-module( priority_queue ).
-module( priority_queue ).


Line 2,355: Line 2,355:


The following Binomial Heap Priority Queue code has been adapted [http://cs.hubfs.net/topic/None/56608 from a version by "DeeJay"] updated for changes in F# over the intervening years, and implementing the O(1) "peekMin" mentioned in that post; in addition to the above standard priority queue functions, it also implements the "merge" function for which the Binomial Heap is particularly suited, taking O(log n) time rather than the usual O(n) (or worse) time:
The following Binomial Heap Priority Queue code has been adapted [http://cs.hubfs.net/topic/None/56608 from a version by "DeeJay"] updated for changes in F# over the intervening years, and implementing the O(1) "peekMin" mentioned in that post; in addition to the above standard priority queue functions, it also implements the "merge" function for which the Binomial Heap is particularly suited, taking O(log n) time rather than the usual O(n) (or worse) time:
<syntaxhighlight lang=fsharp>[<RequireQualifiedAccess>]
<syntaxhighlight lang="fsharp">[<RequireQualifiedAccess>]
module PriorityQ =
module PriorityQ =


Line 2,470: Line 2,470:


The following code implementing a Min Heap Priority Queue is adapted from the [http://www.cl.cam.ac.uk/~lp15/MLbook/programs/sample4.sml ML PRIORITY_QUEUE code by Lawrence C. Paulson] including separating the key/value pairs as separate entries in the data structure for better comparison efficiency; it implements an efficient "fromSeq" function using reheapify for which the Min Heap is particularly suited as it has only O(n) instead of O(n log n) computational time complexity, which method is also used for the "adjust" and "merge" functions:
The following code implementing a Min Heap Priority Queue is adapted from the [http://www.cl.cam.ac.uk/~lp15/MLbook/programs/sample4.sml ML PRIORITY_QUEUE code by Lawrence C. Paulson] including separating the key/value pairs as separate entries in the data structure for better comparison efficiency; it implements an efficient "fromSeq" function using reheapify for which the Min Heap is particularly suited as it has only O(n) instead of O(n log n) computational time complexity, which method is also used for the "adjust" and "merge" functions:
<syntaxhighlight lang=fsharp>[<RequireQualifiedAccess>]
<syntaxhighlight lang="fsharp">[<RequireQualifiedAccess>]
module PriorityQ =
module PriorityQ =


Line 2,613: Line 2,613:


As the Min Heap is usually implemented as a [http://opendatastructures.org/versions/edition-0.1e/ods-java/10_1_BinaryHeap_Implicit_Bi.html mutable array binary heap] after a genealogical tree based model invented by [https://en.wikipedia.org/wiki/Michael_Eytzinger Michael Eytzinger] over 400 years ago, the following "ugly imperative" code implements the Min Heap Priority Queue this way; note that the code could be implemented not using "ugly" mutable state variables other than the contents of the array (DotNet List which implements a growable array) but in this case the code would be considerably slower as in not much faster or slower than the functional version since using mutable side effects greatly reduces the number of operations:
As the Min Heap is usually implemented as a [http://opendatastructures.org/versions/edition-0.1e/ods-java/10_1_BinaryHeap_Implicit_Bi.html mutable array binary heap] after a genealogical tree based model invented by [https://en.wikipedia.org/wiki/Michael_Eytzinger Michael Eytzinger] over 400 years ago, the following "ugly imperative" code implements the Min Heap Priority Queue this way; note that the code could be implemented not using "ugly" mutable state variables other than the contents of the array (DotNet List which implements a growable array) but in this case the code would be considerably slower as in not much faster or slower than the functional version since using mutable side effects greatly reduces the number of operations:
<syntaxhighlight lang=fsharp>[<RequireQualifiedAccess>]
<syntaxhighlight lang="fsharp">[<RequireQualifiedAccess>]
module PriorityQ =
module PriorityQ =


Line 2,701: Line 2,701:


All of the above codes can be tested under the F# REPL using the following:
All of the above codes can be tested under the F# REPL using the following:
<syntaxhighlight lang=fsharp>> let testseq = [| (3u, "Clear drains");
<syntaxhighlight lang="fsharp">> let testseq = [| (3u, "Clear drains");
(4u, "Feed cat");
(4u, "Feed cat");
(5u, "Make tea");
(5u, "Make tea");
Line 2,765: Line 2,765:
=={{header|Factor}}==
=={{header|Factor}}==
Factor has priority queues implemented in the library: documentation is available at http://docs.factorcode.org/content/article-heaps.html (or by typing "heaps" help interactively in the listener).
Factor has priority queues implemented in the library: documentation is available at http://docs.factorcode.org/content/article-heaps.html (or by typing "heaps" help interactively in the listener).
<syntaxhighlight lang=factor><min-heap> [ {
<syntaxhighlight lang="factor"><min-heap> [ {
{ 3 "Clear drains" }
{ 3 "Clear drains" }
{ 4 "Feed cat" }
{ 4 "Feed cat" }
Line 2,777: Line 2,777:


output:
output:
<syntaxhighlight lang=factor>Solve RC tasks
<syntaxhighlight lang="factor">Solve RC tasks
Tax return
Tax return
Clear drains
Clear drains
Line 2,786: Line 2,786:
{{works with|gforth|0.7.3}}
{{works with|gforth|0.7.3}}
<br>
<br>
<syntaxhighlight lang=forth>#! /usr/bin/gforth
<syntaxhighlight lang="forth">#! /usr/bin/gforth


\ Priority queue
\ Priority queue
Line 2,982: Line 2,982:


=={{header|Fortran}}==
=={{header|Fortran}}==
<syntaxhighlight lang=Fortran>module priority_queue_mod
<syntaxhighlight lang="fortran">module priority_queue_mod
implicit none
implicit none


Line 3,088: Line 3,088:
=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==
{{trans|VBA}}
{{trans|VBA}}
<syntaxhighlight lang=freebasic>Type Tupla
<syntaxhighlight lang="freebasic">Type Tupla
Prioridad As Integer
Prioridad As Integer
Tarea As String
Tarea As String
Line 3,181: Line 3,181:


=={{header|FunL}}==
=={{header|FunL}}==
<syntaxhighlight lang=funl>import util.ordering
<syntaxhighlight lang="funl">import util.ordering
native scala.collection.mutable.PriorityQueue
native scala.collection.mutable.PriorityQueue


Line 3,217: Line 3,217:
Go's standard library contains the <code>container/heap</code> package, which which provides operations to operate as a heap any data structure that contains the <code>Push</code>, <code>Pop</code>, <code>Len</code>, <code>Less</code>, and <code>Swap</code> methods.
Go's standard library contains the <code>container/heap</code> package, which which provides operations to operate as a heap any data structure that contains the <code>Push</code>, <code>Pop</code>, <code>Len</code>, <code>Less</code>, and <code>Swap</code> methods.


<syntaxhighlight lang=go>package main
<syntaxhighlight lang="go">package main


import (
import (
Line 3,272: Line 3,272:
=={{header|Groovy}}==
=={{header|Groovy}}==
Groovy can use the built in java PriorityQueue class
Groovy can use the built in java PriorityQueue class
<syntaxhighlight lang=groovy>import groovy.transform.Canonical
<syntaxhighlight lang="groovy">import groovy.transform.Canonical


@Canonical
@Canonical
Line 3,300: Line 3,300:
=={{header|Haskell}}==
=={{header|Haskell}}==
One of the best Haskell implementations of priority queues (of which there are many) is [http://hackage.haskell.org/package/pqueue pqueue], which implements a binomial heap.
One of the best Haskell implementations of priority queues (of which there are many) is [http://hackage.haskell.org/package/pqueue pqueue], which implements a binomial heap.
<syntaxhighlight lang=haskell>import Data.PQueue.Prio.Min
<syntaxhighlight lang="haskell">import Data.PQueue.Prio.Min


main = print (toList (fromList [(3, "Clear drains"),(4, "Feed cat"),(5, "Make tea"),(1, "Solve RC tasks"), (2, "Tax return")]))</syntaxhighlight>
main = print (toList (fromList [(3, "Clear drains"),(4, "Feed cat"),(5, "Make tea"),(1, "Solve RC tasks"), (2, "Tax return")]))</syntaxhighlight>


Although Haskell's standard library does not have a dedicated priority queue structure, one can (for most purposes) use the built-in <code>Data.Set</code> data structure as a priority queue, as long as no two elements compare equal (since Set does not allow duplicate elements). This is the case here since no two tasks should have the same name. The complexity of all basic operations is still O(log n) although that includes the "elemAt 0" function to retrieve the first element of the ordered sequence if that were required; "fromList" takes O(n log n) and "toList" takes O(n) time complexity. Alternatively, a <code>Data.Map.Lazy</code> or <code>Data.Map.Strict</code> can be used in the same way with the same limitations.
Although Haskell's standard library does not have a dedicated priority queue structure, one can (for most purposes) use the built-in <code>Data.Set</code> data structure as a priority queue, as long as no two elements compare equal (since Set does not allow duplicate elements). This is the case here since no two tasks should have the same name. The complexity of all basic operations is still O(log n) although that includes the "elemAt 0" function to retrieve the first element of the ordered sequence if that were required; "fromList" takes O(n log n) and "toList" takes O(n) time complexity. Alternatively, a <code>Data.Map.Lazy</code> or <code>Data.Map.Strict</code> can be used in the same way with the same limitations.
<syntaxhighlight lang=haskell>import qualified Data.Set as S
<syntaxhighlight lang="haskell">import qualified Data.Set as S


main = print (S.toList (S.fromList [(3, "Clear drains"),(4, "Feed cat"),(5, "Make tea"),(1, "Solve RC tasks"), (2, "Tax return")]))</syntaxhighlight>
main = print (S.toList (S.fromList [(3, "Clear drains"),(4, "Feed cat"),(5, "Make tea"),(1, "Solve RC tasks"), (2, "Tax return")]))</syntaxhighlight>
Line 3,312: Line 3,312:


Alternatively, a homemade min heap implementation:
Alternatively, a homemade min heap implementation:
<syntaxhighlight lang=haskell>data MinHeap a = Nil | MinHeap { v::a, cnt::Int, l::MinHeap a, r::MinHeap a }
<syntaxhighlight lang="haskell">data MinHeap a = Nil | MinHeap { v::a, cnt::Int, l::MinHeap a, r::MinHeap a }
deriving (Show, Eq)
deriving (Show, Eq)


Line 3,357: Line 3,357:


The above code is a Priority Queue but isn't a [https://en.wikipedia.org/wiki/Binary_heap Min Heap based on a Binary Heap] for the following reasons: 1) it does not preserve the standard tree structure of the binary heap and 2) the tree balancing can be completely destroyed by some combinations of "pop" operations. The following code is a true purely functional Min Heap implementation and as well implements the extra optional features of Min Heap's that it can build a new Min Heap from a list in O(n) amortized time rather than the O(n log n) amortized time (for a large number of randomly ordered entries) by simply using repeated "push" operations; as well as the standard "push", "peek", "delete" and "pop" (combines the previous two). As well as the "fromList", "toList", and "sort" functions (the last combines the first two), it also has an "isEmpty" function to test for the empty queue, an "adjust" function that applies a function to every entry in the queue and reheapifies in O(n) amortized time and also the "replaceMin" function which is about twice as fast on the average as combined "delete" followed by "push" operations:
The above code is a Priority Queue but isn't a [https://en.wikipedia.org/wiki/Binary_heap Min Heap based on a Binary Heap] for the following reasons: 1) it does not preserve the standard tree structure of the binary heap and 2) the tree balancing can be completely destroyed by some combinations of "pop" operations. The following code is a true purely functional Min Heap implementation and as well implements the extra optional features of Min Heap's that it can build a new Min Heap from a list in O(n) amortized time rather than the O(n log n) amortized time (for a large number of randomly ordered entries) by simply using repeated "push" operations; as well as the standard "push", "peek", "delete" and "pop" (combines the previous two). As well as the "fromList", "toList", and "sort" functions (the last combines the first two), it also has an "isEmpty" function to test for the empty queue, an "adjust" function that applies a function to every entry in the queue and reheapifies in O(n) amortized time and also the "replaceMin" function which is about twice as fast on the average as combined "delete" followed by "push" operations:
<syntaxhighlight lang=haskell>data MinHeap kv = MinHeapEmpty
<syntaxhighlight lang="haskell">data MinHeap kv = MinHeapEmpty
| MinHeapLeaf !kv
| MinHeapLeaf !kv
| MinHeapNode !kv {-# UNPACK #-} !Int !(MinHeap a) !(MinHeap a)
| MinHeapNode !kv {-# UNPACK #-} !Int !(MinHeap a) !(MinHeap a)
Line 3,483: Line 3,483:


If one is willing to forgo the fast O(1) "size" function and to give up strict conformance to the Heap tree structure (where rather than building each new level until each left node is full to that level before increasing level to the right, a new level is built by promoting leaves to branches only containing left leaves until all branches have left leaves before filling any right leaves of that level) although having even better tree balancing and therefore at least as high efficiency, one can use the following code adapted from the [http://www.cl.cam.ac.uk/~lp15/MLbook/programs/sample4.sml ''ML'' PRIORITY_QUEUE code by Lawrence C. Paulson] including separating the key/value pairs as separate entries in the data structure for better comparison efficiency; as noted in the code comments, a "size" function to output the number of elements in the queue (fairly quickly in O((log n)^2)), an "adjust" function to apply a function to all elements and reheapify in O(n) time, and a "merge" function to merge two queues has been added to the ML code:
If one is willing to forgo the fast O(1) "size" function and to give up strict conformance to the Heap tree structure (where rather than building each new level until each left node is full to that level before increasing level to the right, a new level is built by promoting leaves to branches only containing left leaves until all branches have left leaves before filling any right leaves of that level) although having even better tree balancing and therefore at least as high efficiency, one can use the following code adapted from the [http://www.cl.cam.ac.uk/~lp15/MLbook/programs/sample4.sml ''ML'' PRIORITY_QUEUE code by Lawrence C. Paulson] including separating the key/value pairs as separate entries in the data structure for better comparison efficiency; as noted in the code comments, a "size" function to output the number of elements in the queue (fairly quickly in O((log n)^2)), an "adjust" function to apply a function to all elements and reheapify in O(n) time, and a "merge" function to merge two queues has been added to the ML code:
<syntaxhighlight lang=haskell>data PriorityQ k v = Mt
<syntaxhighlight lang="haskell">data PriorityQ k v = Mt
| Br !k v !(PriorityQ k v) !(PriorityQ k v)
| Br !k v !(PriorityQ k v) !(PriorityQ k v)
deriving (Eq, Ord, Read, Show)
deriving (Eq, Ord, Read, Show)
Line 3,595: Line 3,595:


The above codes when tested with the following "main" function (with a slight modification for the first test when the combined kv entry is used):
The above codes when tested with the following "main" function (with a slight modification for the first test when the combined kv entry is used):
<syntaxhighlight lang=haskell>testList = [ (3, "Clear drains"),
<syntaxhighlight lang="haskell">testList = [ (3, "Clear drains"),
(4, "Feed cat"),
(4, "Feed cat"),
(5, "Make tea"),
(5, "Make tea"),
Line 3,658: Line 3,658:
<tt>Closure</tt> is used to allow the queue to order lists based on
<tt>Closure</tt> is used to allow the queue to order lists based on
their first element. The solution only works in Unicon.
their first element. The solution only works in Unicon.
<syntaxhighlight lang=Unicon>import Utils # For Closure class
<syntaxhighlight lang="unicon">import Utils # For Closure class
import Collections # For Heap (dense priority queue) class
import Collections # For Heap (dense priority queue) class


Line 3,685: Line 3,685:
Implementation:
Implementation:


<syntaxhighlight lang=j>coclass 'priorityQueue'
<syntaxhighlight lang="j">coclass 'priorityQueue'


PRI=: ''
PRI=: ''
Line 3,713: Line 3,713:
Example:
Example:


<syntaxhighlight lang=j> Q=: conew'priorityQueue'
<syntaxhighlight lang="j"> Q=: conew'priorityQueue'
3 4 5 1 2 insert__Q 'clear drains';'feed cat';'make tea';'solve rc task';'tax return'
3 4 5 1 2 insert__Q 'clear drains';'feed cat';'make tea';'solve rc task';'tax return'
>topN__Q 1
>topN__Q 1
Line 3,726: Line 3,726:
Java has a <code>PriorityQueue</code> class. It requires either the elements implement <code>Comparable</code>, or you give it a custom <code>Comparator</code> to compare the elements.
Java has a <code>PriorityQueue</code> class. It requires either the elements implement <code>Comparable</code>, or you give it a custom <code>Comparator</code> to compare the elements.


<syntaxhighlight lang=java>import java.util.PriorityQueue;
<syntaxhighlight lang="java">import java.util.PriorityQueue;


class Task implements Comparable<Task> {
class Task implements Comparable<Task> {
Line 3,771: Line 3,771:
The special key "priorities" is used to store the priorities in a sorted array. Since "sort" is fast we will use that rather than optimizing insertion in the priorities array.
The special key "priorities" is used to store the priorities in a sorted array. Since "sort" is fast we will use that rather than optimizing insertion in the priorities array.


We assume that if an item of a given priority is already in the priority queue, there is no need to add it again.<syntaxhighlight lang=jq># In the following, pq stands for "priority queue".
We assume that if an item of a given priority is already in the priority queue, there is no need to add it again.<syntaxhighlight lang="jq"># In the following, pq stands for "priority queue".


# Add an item with the given priority (an integer,
# Add an item with the given priority (an integer,
Line 3,822: Line 3,822:
</syntaxhighlight>
</syntaxhighlight>
The specific task:
The specific task:
<syntaxhighlight lang=jq>
<syntaxhighlight lang="jq">
[ [3, "Clear drains"],
[ [3, "Clear drains"],
[4, "Feed cat"],
[4, "Feed cat"],
Line 3,839: Line 3,839:
=={{header|Julia}}==
=={{header|Julia}}==
Julia has built-in support for priority queues, though the <code>PriorityQueue</code> type is not exported by default. Priority queues are a specialization of the <code>Dictionary</code> type having ordered values, which serve as the priority. In addition to all of the methods of standard dictionaries, priority queues support: <code>enqueue!</code>, which adds an item to the queue, <code>dequeue!</code> which removes the lowest priority item from the queue, returning its key, and <code>peek</code>, which returns the (key, priority) of the lowest priority entry in the queue. The ordering behavior of the queue, which by default is its value sort order (typically low to high), can be set by passing an order directive to its constructor. For this task, <code>Base.Order.Reverse</code> is used to set-up the <code>task</code> queue to return tasks from high to low priority.
Julia has built-in support for priority queues, though the <code>PriorityQueue</code> type is not exported by default. Priority queues are a specialization of the <code>Dictionary</code> type having ordered values, which serve as the priority. In addition to all of the methods of standard dictionaries, priority queues support: <code>enqueue!</code>, which adds an item to the queue, <code>dequeue!</code> which removes the lowest priority item from the queue, returning its key, and <code>peek</code>, which returns the (key, priority) of the lowest priority entry in the queue. The ordering behavior of the queue, which by default is its value sort order (typically low to high), can be set by passing an order directive to its constructor. For this task, <code>Base.Order.Reverse</code> is used to set-up the <code>task</code> queue to return tasks from high to low priority.
<syntaxhighlight lang=Julia>
<syntaxhighlight lang="julia">
using Base.Collections
using Base.Collections


Line 3,871: Line 3,871:
=={{header|Kotlin}}==
=={{header|Kotlin}}==
{{trans|Java}}
{{trans|Java}}
<syntaxhighlight lang=scala>import java.util.PriorityQueue
<syntaxhighlight lang="scala">import java.util.PriorityQueue


internal data class Task(val priority: Int, val name: String) : Comparable<Task> {
internal data class Task(val priority: Int, val name: String) : Comparable<Task> {
Line 3,899: Line 3,899:


=={{header|Lasso}}==
=={{header|Lasso}}==
<syntaxhighlight lang=lasso>define priorityQueue => type {
<syntaxhighlight lang="lasso">define priorityQueue => type {
data
data
store = map,
store = map,
Line 3,966: Line 3,966:
This implementation uses a table with priorities as keys and queues as values. Queues for each priority are created when putting items as needed and are shrunk as necessary when popping items and removed when they are empty. Instead of using a plain array table for each queue, the technique shown in the Lua implementation from the [[Queue/Definition#Lua | Queue]] task is used. This avoids having to use <code>table.remove(t, 1)</code> to get and remove the first queue element, which is rather slow for big tables.
This implementation uses a table with priorities as keys and queues as values. Queues for each priority are created when putting items as needed and are shrunk as necessary when popping items and removed when they are empty. Instead of using a plain array table for each queue, the technique shown in the Lua implementation from the [[Queue/Definition#Lua | Queue]] task is used. This avoids having to use <code>table.remove(t, 1)</code> to get and remove the first queue element, which is rather slow for big tables.


<syntaxhighlight lang=lua>PriorityQueue = {
<syntaxhighlight lang="lua">PriorityQueue = {
__index = {
__index = {
put = function(self, p, v)
put = function(self, p, v)
Line 4,032: Line 4,032:
The implementation is faster than the Python implementations below using <code>queue.PriorityQueue</code> or <code>heapq</code>, even when comparing the standard Lua implementation against [[PyPy]] and millions of tasks are added to the queue. With LuaJIT it is yet faster. The following code measures the time needed to add 10<sup>7</sup> tasks with a random priority between 1 and 1000 and to retrieve them from the queue again in order.
The implementation is faster than the Python implementations below using <code>queue.PriorityQueue</code> or <code>heapq</code>, even when comparing the standard Lua implementation against [[PyPy]] and millions of tasks are added to the queue. With LuaJIT it is yet faster. The following code measures the time needed to add 10<sup>7</sup> tasks with a random priority between 1 and 1000 and to retrieve them from the queue again in order.


<syntaxhighlight lang=lua>-- Use socket.gettime() for benchmark measurements
<syntaxhighlight lang="lua">-- Use socket.gettime() for benchmark measurements
-- since it has millisecond precision on most systems
-- since it has millisecond precision on most systems
local socket = require("socket")
local socket = require("socket")
Line 4,077: Line 4,077:


===Using unordered array===
===Using unordered array===
<syntaxhighlight lang=M2000 Interpreter>
<syntaxhighlight lang="m2000 interpreter">
Module UnOrderedArray {
Module UnOrderedArray {
Class PriorityQueue {
Class PriorityQueue {
Line 4,198: Line 4,198:
===Using a stack with arrays as elements===
===Using a stack with arrays as elements===
Every insertion push item using binary search in proper position. Pop is very fast.
Every insertion push item using binary search in proper position. Pop is very fast.
<syntaxhighlight lang=M2000 Interpreter>
<syntaxhighlight lang="m2000 interpreter">
Module PriorityQueue {
Module PriorityQueue {
a= ( (3, "Clear drains"), (4 ,"Feed cat"), ( 5 , "Make tea"), ( 1 ,"Solve RC tasks"), ( 2 , "Tax return"))
a= ( (3, "Clear drains"), (4 ,"Feed cat"), ( 5 , "Make tea"), ( 1 ,"Solve RC tasks"), ( 2 , "Tax return"))
Line 4,265: Line 4,265:
This is the same as previous but now we use a group (a user object for M2000). InsertPQ is the same as before. Lambda comp has change only. We didn't use pointers to groups. All groups here works as values, so when we get a peek we get a copy of group in top position. All members of a group may not values, so if we have a pointer to group then we get a copy of that pointer, but then we can make changes and that changes happen for the group which we get the copy.
This is the same as previous but now we use a group (a user object for M2000). InsertPQ is the same as before. Lambda comp has change only. We didn't use pointers to groups. All groups here works as values, so when we get a peek we get a copy of group in top position. All members of a group may not values, so if we have a pointer to group then we get a copy of that pointer, but then we can make changes and that changes happen for the group which we get the copy.


<syntaxhighlight lang=M2000 Interpreter>
<syntaxhighlight lang="m2000 interpreter">
Module PriorityQueueForGroups {
Module PriorityQueueForGroups {
class obj {
class obj {
Line 4,326: Line 4,326:


=={{header|Mathematica}}/{{header|Wolfram Language}}==
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang=mathematica>push = Function[{queue, priority, item},
<syntaxhighlight lang="mathematica">push = Function[{queue, priority, item},
queue = SortBy[Append[queue, {priority, item}], First], HoldFirst];
queue = SortBy[Append[queue, {priority, item}], First], HoldFirst];
pop = Function[queue,
pop = Function[queue,
Line 4,339: Line 4,339:
Example:
Example:


<syntaxhighlight lang=mathematica>queue = {};
<syntaxhighlight lang="mathematica">queue = {};
push[queue, 3, "Clear drains"];
push[queue, 3, "Clear drains"];
push[queue, 4, "Feed cat"];
push[queue, 4, "Feed cat"];
Line 4,360: Line 4,360:


=={{header|Maxima}}==
=={{header|Maxima}}==
<syntaxhighlight lang=maxima>/* Naive implementation using a sorted list of pairs [key, [item[1], ..., item[n]]].
<syntaxhighlight lang="maxima">/* Naive implementation using a sorted list of pairs [key, [item[1], ..., item[n]]].
The key may be any number (integer or not). Items are extracted in FIFO order. */
The key may be any number (integer or not). Items are extracted in FIFO order. */


Line 4,446: Line 4,446:
Mercury comes with an efficient, albeit simple, priority queue in its standard library. The build_pqueue/2 predicate in the code below inserts the test data in arbitrary order. display_pqueue/3, in turn, removes one K/V pair at a time, displaying the value. Compiling and running the supplied program results in all tasks being displayed in priority order as expected.
Mercury comes with an efficient, albeit simple, priority queue in its standard library. The build_pqueue/2 predicate in the code below inserts the test data in arbitrary order. display_pqueue/3, in turn, removes one K/V pair at a time, displaying the value. Compiling and running the supplied program results in all tasks being displayed in priority order as expected.


<syntaxhighlight lang=mercury>:- module test_pqueue.
<syntaxhighlight lang="mercury">:- module test_pqueue.


:- interface.
:- interface.
Line 4,484: Line 4,484:
=={{header|Nim}}==
=={{header|Nim}}==
{{trans|C}}
{{trans|C}}
<syntaxhighlight lang=nim>type
<syntaxhighlight lang="nim">type
PriElem[T] = tuple
PriElem[T] = tuple
data: T
data: T
Line 4,552: Line 4,552:


''' Using Nim HeapQueue'''
''' Using Nim HeapQueue'''
<syntaxhighlight lang=Nim>import HeapQueue
<syntaxhighlight lang="nim">import HeapQueue


var pq = newHeapQueue[(int, string)]()
var pq = newHeapQueue[(int, string)]()
Line 4,573: Line 4,573:


''' Using Nim tables'''
''' Using Nim tables'''
<syntaxhighlight lang=Nim>import tables
<syntaxhighlight lang="nim">import tables


var
var
Line 4,602: Line 4,602:
The priority queue used in this example is not actually written in Objective-C. It is part of Apple's (C-based) Core Foundation library, which is included with in Cocoa on Mac OS X and iOS. Its interface is a C function interface, which makes the code very ugly. Core Foundation is not included in GNUStep or other Objective-C APIs.
The priority queue used in this example is not actually written in Objective-C. It is part of Apple's (C-based) Core Foundation library, which is included with in Cocoa on Mac OS X and iOS. Its interface is a C function interface, which makes the code very ugly. Core Foundation is not included in GNUStep or other Objective-C APIs.


<syntaxhighlight lang=objc>#import <Foundation/Foundation.h>
<syntaxhighlight lang="objc">#import <Foundation/Foundation.h>


const void *PQRetain(CFAllocatorRef allocator, const void *ptr) {
const void *PQRetain(CFAllocatorRef allocator, const void *ptr) {
Line 4,680: Line 4,680:
Holger Arnold's [http://holgerarnold.net/software/ OCaml base library] provides a [http://holgerarnold.net/software/ocaml/doc/base/PriorityQueue.html PriorityQueue] module.
Holger Arnold's [http://holgerarnold.net/software/ OCaml base library] provides a [http://holgerarnold.net/software/ocaml/doc/base/PriorityQueue.html PriorityQueue] module.


<syntaxhighlight lang=ocaml>module PQ = Base.PriorityQueue
<syntaxhighlight lang="ocaml">module PQ = Base.PriorityQueue


let () =
let () =
Line 4,708: Line 4,708:
Although OCaml's standard library does not have a dedicated priority queue structure, one can (for most purposes) use the built-in Set data structure as a priority queue, as long as no two elements compare equal (since Set does not allow duplicate elements). This is the case here since no two tasks should have the same name. Note that Set is a functional, persistent data structure, so we derive new priority queues from the old ones functionally, rather than modifying them imperatively; the complexity is still O(log n).
Although OCaml's standard library does not have a dedicated priority queue structure, one can (for most purposes) use the built-in Set data structure as a priority queue, as long as no two elements compare equal (since Set does not allow duplicate elements). This is the case here since no two tasks should have the same name. Note that Set is a functional, persistent data structure, so we derive new priority queues from the old ones functionally, rather than modifying them imperatively; the complexity is still O(log n).
{{works with|OCaml|4.02+}}
{{works with|OCaml|4.02+}}
<syntaxhighlight lang=ocaml>module PQSet = Set.Make
<syntaxhighlight lang="ocaml">module PQSet = Set.Make
(struct
(struct
type t = int * string (* pair of priority and task name *)
type t = int * string (* pair of priority and task name *)
Line 4,739: Line 4,739:
</pre>
</pre>
=={{header|OxygenBasic}}==
=={{header|OxygenBasic}}==
<lang>
<syntaxhighlight lang="text">
'PRIORITY QUEUE WITH 16 LEVELS
'PRIORITY QUEUE WITH 16 LEVELS


Line 4,908: Line 4,908:


=={{header|Pascal}}==
=={{header|Pascal}}==
<syntaxhighlight lang=Pascal>
<syntaxhighlight lang="pascal">
program PriorityQueueTest;
program PriorityQueueTest;


Line 4,987: Line 4,987:
=={{header|Perl}}==
=={{header|Perl}}==
There are a few implementations on CPAN. Following uses <code>Heap::Priority</code>[http://search.cpan.org/~fwojcik/Heap-Priority-0.11/Priority.pm]
There are a few implementations on CPAN. Following uses <code>Heap::Priority</code>[http://search.cpan.org/~fwojcik/Heap-Priority-0.11/Priority.pm]
<syntaxhighlight lang=perl>use 5.10.0;
<syntaxhighlight lang="perl">use 5.10.0;
use strict;
use strict;
use Heap::Priority;
use Heap::Priority;
Line 5,000: Line 5,000:
["Tax return", 2];
["Tax return", 2];


say while ($_ = $h->pop);</syntaxhighlight>output<lang>Make tea
say while ($_ = $h->pop);</syntaxhighlight>output<syntaxhighlight lang="text">Make tea
Feed cat
Feed cat
Clear drains
Clear drains
Line 5,006: Line 5,006:
Solve RC tasks</syntaxhighlight>
Solve RC tasks</syntaxhighlight>
===IBM card sorter version===
===IBM card sorter version===
<syntaxhighlight lang=perl>#!/usr/bin/perl
<syntaxhighlight lang="perl">#!/usr/bin/perl


use strict; # https://rosettacode.org/wiki/Priority_queue
use strict; # https://rosettacode.org/wiki/Priority_queue
Line 5,052: Line 5,052:
Dictionary based solution. Allows duplicate tasks, FIFO within priority, and uses a callback-style method of performing tasks.<br>
Dictionary based solution. Allows duplicate tasks, FIFO within priority, and uses a callback-style method of performing tasks.<br>
Assumes 5 is the highest priority and should be done first, for 1 first just delete the ",true" on traverse_dict calls.
Assumes 5 is the highest priority and should be done first, for 1 first just delete the ",true" on traverse_dict calls.
<!--<syntaxhighlight lang=Phix>(phixonline)-->
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">tasklist</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new_dict</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">tasklist</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new_dict</span><span style="color: #0000FF;">()</span>
Line 5,128: Line 5,128:
(I needed this for [[Taxicab_numbers#Phix|Taxicab_numbers]])<br>
(I needed this for [[Taxicab_numbers#Phix|Taxicab_numbers]])<br>
The bulk of this code now forms builtins/pqueue.e (not properly documented at the time, but now is, see below)
The bulk of this code now forms builtins/pqueue.e (not properly documented at the time, but now is, see below)
<!--<syntaxhighlight lang=Phix>(phixonline)-->
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">pq</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">pq</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
Line 5,204: Line 5,204:
=== builtin ===
=== builtin ===
If you omit MAX_HEAP or (same thing) specify MIN_HEAP, the output'll be 1..5
If you omit MAX_HEAP or (same thing) specify MIN_HEAP, the output'll be 1..5
<!--<syntaxhighlight lang=Phix>(phixonline)-->
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">tasklist</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">pq_new</span><span style="color: #0000FF;">(</span><span style="color: #004600;">MAX_HEAP</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">tasklist</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">pq_new</span><span style="color: #0000FF;">(</span><span style="color: #004600;">MAX_HEAP</span><span style="color: #0000FF;">)</span>
Line 5,229: Line 5,229:


=={{header|Phixmonti}}==
=={{header|Phixmonti}}==
<syntaxhighlight lang=Phixmonti>/# Rosetta Code problem: http://rosettacode.org/wiki/Priority_queue
<syntaxhighlight lang="phixmonti">/# Rosetta Code problem: http://rosettacode.org/wiki/Priority_queue
by Galileo, 05/2022 #/
by Galileo, 05/2022 #/


Line 5,247: Line 5,247:
{{works with|PHP|5.3+}}
{{works with|PHP|5.3+}}
PHP's <code>SplPriorityQueue</code> class implements a max-heap. PHP also separately has <code>SplHeap</code>, <code>SplMinHeap</code>, and <code>SplMaxHeap</code> classes.
PHP's <code>SplPriorityQueue</code> class implements a max-heap. PHP also separately has <code>SplHeap</code>, <code>SplMinHeap</code>, and <code>SplMaxHeap</code> classes.
<syntaxhighlight lang=php><?php
<syntaxhighlight lang="php"><?php
$pq = new SplPriorityQueue;
$pq = new SplPriorityQueue;


Line 5,296: Line 5,296:
{{works with|PHP|5.3+}}
{{works with|PHP|5.3+}}
The difference between <code>SplHeap</code> and <code>SplPriorityQueue</code> is that <code>SplPriorityQueue</code> takes the data and the priority as two separate arguments, and the comparison is only made on the priority; whereas <code>SplHeap</code> takes only one argument (the element), and the comparison is made on that directly. In all of these classes it is possible to provide a custom comparator by subclassing the class and overriding its <code>compare</code> method.
The difference between <code>SplHeap</code> and <code>SplPriorityQueue</code> is that <code>SplPriorityQueue</code> takes the data and the priority as two separate arguments, and the comparison is only made on the priority; whereas <code>SplHeap</code> takes only one argument (the element), and the comparison is made on that directly. In all of these classes it is possible to provide a custom comparator by subclassing the class and overriding its <code>compare</code> method.
<syntaxhighlight lang=php><?php
<syntaxhighlight lang="php"><?php
$pq = new SplMinHeap;
$pq = new SplMinHeap;
Line 5,341: Line 5,341:
=={{header|Picat}}==
=={{header|Picat}}==
Picat has built-in support for min and max heaps.
Picat has built-in support for min and max heaps.
<syntaxhighlight lang=Picat>main =>
<syntaxhighlight lang="picat">main =>
Tasks = [[3,"Clear drains"],
Tasks = [[3,"Clear drains"],
[4,"Feed cat"],
[4,"Feed cat"],
Line 5,373: Line 5,373:


The heaps creation functions can take the task list as argument:
The heaps creation functions can take the task list as argument:
<syntaxhighlight lang=Picat> Tasks = [[3,"Clear drains"],
<syntaxhighlight lang="picat"> Tasks = [[3,"Clear drains"],
[4,"Feed cat"],
[4,"Feed cat"],
[5,"Make tea"],
[5,"Make tea"],
Line 5,384: Line 5,384:
=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
The following implementation imposes no limits. It uses a [http://software-lab.de/doc/refI.html#idx binary tree] for storage. The priority levels may be numeric, or of any other type.
The following implementation imposes no limits. It uses a [http://software-lab.de/doc/refI.html#idx binary tree] for storage. The priority levels may be numeric, or of any other type.
<syntaxhighlight lang=PicoLisp># Insert item into priority queue
<syntaxhighlight lang="picolisp"># Insert item into priority queue
(de insertPQ (Queue Prio Item)
(de insertPQ (Queue Prio Item)
(idx Queue (cons Prio Item) T) )
(idx Queue (cons Prio Item) T) )
Line 5,403: Line 5,403:
(balance Queue1 (sort (conc (idx Queue1) (idx Queue2)))) )</syntaxhighlight>
(balance Queue1 (sort (conc (idx Queue1) (idx Queue2)))) )</syntaxhighlight>
Test:
Test:
<syntaxhighlight lang=PicoLisp># Two priority queues
<syntaxhighlight lang="picolisp"># Two priority queues
(off Pq1 Pq2)
(off Pq1 Pq2)


Line 5,428: Line 5,428:
(Make tea)</pre>
(Make tea)</pre>
=== Alternative version using a pairing heap: ===
=== Alternative version using a pairing heap: ===
<syntaxhighlight lang=PicoLisp>
<syntaxhighlight lang="picolisp">
(de heap-first (H) (car H))
(de heap-first (H) (car H))


Line 5,454: Line 5,454:
</syntaxhighlight>
</syntaxhighlight>
Test:
Test:
<syntaxhighlight lang=PicoLisp>
<syntaxhighlight lang="picolisp">
(setq H NIL)
(setq H NIL)
(for
(for
Line 5,485: Line 5,485:


Example of use :
Example of use :
<syntaxhighlight lang=Prolog>priority-queue :-
<syntaxhighlight lang="prolog">priority-queue :-
TL0 = [3-'Clear drains',
TL0 = [3-'Clear drains',
4-'Feed cat'],
4-'Feed cat'],
Line 5,537: Line 5,537:
The map stores the elements of a given priority in a FIFO list.
The map stores the elements of a given priority in a FIFO list.
Priorities can be any signed 32 value.
Priorities can be any signed 32 value.
<syntaxhighlight lang=purebasic>Structure taskList
<syntaxhighlight lang="purebasic">Structure taskList
List description.s() ;implements FIFO queue
List description.s() ;implements FIFO queue
EndStructure
EndStructure
Line 5,675: Line 5,675:


The data structures in the "queue" module are synchronized multi-producer, multi-consumer queues for multi-threaded use. They can however handle this task:
The data structures in the "queue" module are synchronized multi-producer, multi-consumer queues for multi-threaded use. They can however handle this task:
<syntaxhighlight lang=python>>>> import queue
<syntaxhighlight lang="python">>>> import queue
>>> pq = queue.PriorityQueue()
>>> pq = queue.PriorityQueue()
>>> for item in ((3, "Clear drains"), (4, "Feed cat"), (5, "Make tea"), (1, "Solve RC tasks"), (2, "Tax return")):
>>> for item in ((3, "Clear drains"), (4, "Feed cat"), (5, "Make tea"), (1, "Solve RC tasks"), (2, "Tax return")):
Line 5,693: Line 5,693:


;Help text for queue.PriorityQueue:
;Help text for queue.PriorityQueue:
<syntaxhighlight lang=python>>>> import queue
<syntaxhighlight lang="python">>>> import queue
>>> help(queue.PriorityQueue)
>>> help(queue.PriorityQueue)
Help on class PriorityQueue in module queue:
Help on class PriorityQueue in module queue:
Line 5,805: Line 5,805:


Although one can use the heappush method to add items individually to a heap similar to the method used in the PriorityQueue example above, we will instead transform the list of items into a heap in one go then pop them off one at a time as before.
Although one can use the heappush method to add items individually to a heap similar to the method used in the PriorityQueue example above, we will instead transform the list of items into a heap in one go then pop them off one at a time as before.
<syntaxhighlight lang=python>>>> from heapq import heappush, heappop, heapify
<syntaxhighlight lang="python">>>> from heapq import heappush, heappop, heapify
>>> items = [(3, "Clear drains"), (4, "Feed cat"), (5, "Make tea"), (1, "Solve RC tasks"), (2, "Tax return")]
>>> items = [(3, "Clear drains"), (4, "Feed cat"), (5, "Make tea"), (1, "Solve RC tasks"), (2, "Tax return")]
>>> heapify(items)
>>> heapify(items)
Line 5,820: Line 5,820:


;Help text for module heapq:
;Help text for module heapq:
<syntaxhighlight lang=python>>>> help('heapq')
<syntaxhighlight lang="python">>>> help('heapq')
Help on module heapq:
Help on module heapq:


Line 5,915: Line 5,915:
For more examples uf usage, see [[Sorting algorithms/Heapsort#Quackery]] and [[Huffman coding#Quackery]]
For more examples uf usage, see [[Sorting algorithms/Heapsort#Quackery]] and [[Huffman coding#Quackery]]


<syntaxhighlight lang=Quackery>( ***** priotity queue ***** )
<syntaxhighlight lang="quackery">( ***** priotity queue ***** )


[ stack ] is heap.pq ( --> s )
[ stack ] is heap.pq ( --> s )
Line 6,025: Line 6,025:
=={{header|R}}==
=={{header|R}}==
Using closures:
Using closures:
<syntaxhighlight lang=R>PriorityQueue <- function() {
<syntaxhighlight lang="r">PriorityQueue <- function() {
keys <- values <- NULL
keys <- values <- NULL
insert <- function(key, value) {
insert <- function(key, value) {
Line 6,050: Line 6,050:
while(!pq$empty()) {
while(!pq$empty()) {
with(pq$pop(), cat(key,":",value,"\n"))
with(pq$pop(), cat(key,":",value,"\n"))
}</syntaxhighlight>With output:<syntaxhighlight lang=R>1 : Solve RC tasks
}</syntaxhighlight>With output:<syntaxhighlight lang="r">1 : Solve RC tasks
2 : Tax return
2 : Tax return
3 : Clear drains
3 : Clear drains
4 : Feed cat
4 : Feed cat
5 : Make tea</syntaxhighlight>A similar implementation using R5 classes:<syntaxhighlight lang=R>PriorityQueue <-
5 : Make tea</syntaxhighlight>A similar implementation using R5 classes:<syntaxhighlight lang="r">PriorityQueue <-
setRefClass("PriorityQueue",
setRefClass("PriorityQueue",
fields = list(keys = "numeric", values = "list"),
fields = list(keys = "numeric", values = "list"),
Line 6,070: Line 6,070:
},
},
empty = function() length(keys) == 0
empty = function() length(keys) == 0
))</syntaxhighlight>The only change in the example would be in the instantiation:<syntaxhighlight lang=R>pq <- PriorityQueue$new()</syntaxhighlight>.
))</syntaxhighlight>The only change in the example would be in the instantiation:<syntaxhighlight lang="r">pq <- PriorityQueue$new()</syntaxhighlight>.


=={{header|Racket}}==
=={{header|Racket}}==
This solution implements priority queues on top of heaps.
This solution implements priority queues on top of heaps.
<syntaxhighlight lang=racket>
<syntaxhighlight lang="racket">
#lang racket
#lang racket
(require data/heap)
(require data/heap)
Line 6,101: Line 6,101:
</syntaxhighlight>
</syntaxhighlight>
Output:
Output:
<syntaxhighlight lang=racket>
<syntaxhighlight lang="racket">
"Solve RC tasks"
"Solve RC tasks"
"Tax return"
"Tax return"
Line 6,115: Line 6,115:
The tasks are stored internally as an array of FIFO buffers, so multiple tasks of the same priority level will be returned in the order they were stored.
The tasks are stored internally as an array of FIFO buffers, so multiple tasks of the same priority level will be returned in the order they were stored.


<syntaxhighlight lang=perl6>class PriorityQueue {
<syntaxhighlight lang="raku" line>class PriorityQueue {
has @!tasks;
has @!tasks;


Line 6,157: Line 6,157:
===version 1===
===version 1===
Programming note: &nbsp; this REXX version allows any number (with or without decimals, say, '''5.7''') for the priority, including negative numbers.
Programming note: &nbsp; this REXX version allows any number (with or without decimals, say, '''5.7''') for the priority, including negative numbers.
<syntaxhighlight lang=rexx>/*REXX program implements a priority queue with insert/display/delete the top task.*/
<syntaxhighlight lang="rexx">/*REXX program implements a priority queue with insert/display/delete the top task.*/
#=0; @.= /*0 tasks; nullify the priority queue.*/
#=0; @.= /*0 tasks; nullify the priority queue.*/
say '══════ inserting tasks.'; call .ins 3 "Clear drains"
say '══════ inserting tasks.'; call .ins 3 "Clear drains"
Line 6,195: Line 6,195:


===version 2===
===version 2===
<syntaxhighlight lang=rexx>/*REXX pgm implements a priority queue; with insert/show/delete top task*/
<syntaxhighlight lang="rexx">/*REXX pgm implements a priority queue; with insert/show/delete top task*/
n=0
n=0
task.=0 /* for the sake of task.0done.* */
task.=0 /* for the sake of task.0done.* */
Line 6,258: Line 6,258:
=={{header|Ruby}}==
=={{header|Ruby}}==
A naive, inefficient implementation
A naive, inefficient implementation
<syntaxhighlight lang=ruby>class PriorityQueueNaive
<syntaxhighlight lang="ruby">class PriorityQueueNaive
def initialize(data=nil)
def initialize(data=nil)
@q = Hash.new {|h, k| h[k] = []}
@q = Hash.new {|h, k| h[k] = []}
Line 6,366: Line 6,366:


=={{header|Run BASIC}}==
=={{header|Run BASIC}}==
<syntaxhighlight lang=runbasic>sqliteconnect #mem, ":memory:"
<syntaxhighlight lang="runbasic">sqliteconnect #mem, ":memory:"
#mem execute("CREATE TABLE queue (priority float,descr text)")
#mem execute("CREATE TABLE queue (priority float,descr text)")


Line 6,427: Line 6,427:


=={{header|Rust}}==
=={{header|Rust}}==
<syntaxhighlight lang=rust>use std::collections::BinaryHeap;
<syntaxhighlight lang="rust">use std::collections::BinaryHeap;
use std::cmp::Ordering;
use std::cmp::Ordering;
use std::borrow::Cow;
use std::borrow::Cow;
Line 6,484: Line 6,484:
=={{header|SAS}}==
=={{header|SAS}}==
Using macros in a SAS data step:
Using macros in a SAS data step:
<syntaxhighlight lang=sas>%macro HeapInit(size=1000,nchar=20);
<syntaxhighlight lang="sas">%macro HeapInit(size=1000,nchar=20);
do;
do;
_len = 0;
_len = 0;
Line 6,588: Line 6,588:


An implementation using <code>proc ds2</code> may be more structured:
An implementation using <code>proc ds2</code> may be more structured:
<syntaxhighlight lang=sas>proc ds2;
<syntaxhighlight lang="sas">proc ds2;
package Heap / overwrite=yes;
package Heap / overwrite=yes;
dcl int _entryorder _size _len _entryOrders[1000];
dcl int _entryorder _size _len _entryOrders[1000];
Line 6,701: Line 6,701:
=={{header|Scala}}==
=={{header|Scala}}==
Scala has a class PriorityQueue in its standard library.
Scala has a class PriorityQueue in its standard library.
<syntaxhighlight lang=scala>import scala.collection.mutable.PriorityQueue
<syntaxhighlight lang="scala">import scala.collection.mutable.PriorityQueue
case class Task(prio:Int, text:String) extends Ordered[Task] {
case class Task(prio:Int, text:String) extends Ordered[Task] {
def compare(that: Task)=that.prio compare this.prio
def compare(that: Task)=that.prio compare this.prio
Line 6,717: Line 6,717:
Task(5,Make tea)</pre>
Task(5,Make tea)</pre>
Instead of deriving the class from Ordering an implicit conversion could be provided.
Instead of deriving the class from Ordering an implicit conversion could be provided.
<syntaxhighlight lang=scala>case class Task(prio:Int, text:String)
<syntaxhighlight lang="scala">case class Task(prio:Int, text:String)
implicit def taskOrdering=new Ordering[Task] {
implicit def taskOrdering=new Ordering[Task] {
def compare(t1:Task, t2:Task):Int=t2.prio compare t1.prio
def compare(t1:Task, t2:Task):Int=t2.prio compare t1.prio
Line 6,724: Line 6,724:
=={{header|SenseTalk}}==
=={{header|SenseTalk}}==
We use New to create an object instance -- in this case (for simplicity) based on the script itself, which is named PriorityQueue. The Tell command or dot notation are then used to send messages directly to that object.
We use New to create an object instance -- in this case (for simplicity) based on the script itself, which is named PriorityQueue. The Tell command or dot notation are then used to send messages directly to that object.
<syntaxhighlight lang=sensetalk>
<syntaxhighlight lang="sensetalk">
// PriorityQueue.script
// PriorityQueue.script
set Tasks to a new PriorityQueue
set Tasks to a new PriorityQueue
Line 6,786: Line 6,786:
=={{header|Sidef}}==
=={{header|Sidef}}==
{{trans|Raku}}
{{trans|Raku}}
<syntaxhighlight lang=ruby>class PriorityQueue {
<syntaxhighlight lang="ruby">class PriorityQueue {
has tasks = []
has tasks = []


Line 6,833: Line 6,833:
Note: this is a max-heap
Note: this is a max-heap


<syntaxhighlight lang=sml>structure TaskPriority = struct
<syntaxhighlight lang="sml">structure TaskPriority = struct
type priority = int
type priority = int
val compare = Int.compare
val compare = Int.compare
Line 6,876: Line 6,876:


Using <code>mata</code>, which has 1-based arrays:
Using <code>mata</code>, which has 1-based arrays:
<syntaxhighlight lang=stata>mata
<syntaxhighlight lang="stata">mata
struct Node {
struct Node {
real scalar time
real scalar time
Line 7,001: Line 7,001:
You can use <code>CFBinaryHeap</code> from Core Foundation, but it is super ugly due to the fact that <code>CFBinaryHeap</code> operates on generic pointers, and you need to convert back and forth between that and objects.
You can use <code>CFBinaryHeap</code> from Core Foundation, but it is super ugly due to the fact that <code>CFBinaryHeap</code> operates on generic pointers, and you need to convert back and forth between that and objects.
{{works with|Swift|2.x}}
{{works with|Swift|2.x}}
<syntaxhighlight lang=swift>class Task : Comparable, CustomStringConvertible {
<syntaxhighlight lang="swift">class Task : Comparable, CustomStringConvertible {
var priority : Int
var priority : Int
var name: String
var name: String
Line 7,069: Line 7,069:
=={{header|Tcl}}==
=={{header|Tcl}}==
{{tcllib|struct::prioqueue}}
{{tcllib|struct::prioqueue}}
<syntaxhighlight lang=tcl>package require struct::prioqueue
<syntaxhighlight lang="tcl">package require struct::prioqueue


set pq [struct::prioqueue]
set pq [struct::prioqueue]
Line 7,098: Line 7,098:
=={{header|uBasic/4tH}}==
=={{header|uBasic/4tH}}==
This implementation inserts items using a binary search. Hence, no sorting is required, since all entries are always in order of priority. It also allows for listing of valid entries.
This implementation inserts items using a binary search. Hence, no sorting is required, since all entries are always in order of priority. It also allows for listing of valid entries.
<lang>b = -1 ' b points to last entry on the queue
<syntaxhighlight lang="text">b = -1 ' b points to last entry on the queue


q = FUNC(_Grab) ' now grab the top value
q = FUNC(_Grab) ' now grab the top value
Line 7,184: Line 7,184:


=={{header|VBA}}==
=={{header|VBA}}==
<syntaxhighlight lang=VB>Type Tuple
<syntaxhighlight lang="vb">Type Tuple
Priority As Integer
Priority As Integer
Data As String
Data As String
Line 7,271: Line 7,271:
=={{header|VBScript}}==
=={{header|VBScript}}==
I wrote this priority queue in a class. It uses a dynamic array to implement the class. Function out_of_order must be adapted to the data. Run it with CScript.
I wrote this priority queue in a class. It uses a dynamic array to implement the class. Function out_of_order must be adapted to the data. Run it with CScript.
<syntaxhighlight lang=vb>
<syntaxhighlight lang="vb">
option explicit
option explicit
Class prio_queue
Class prio_queue
Line 7,392: Line 7,392:
{{libheader|Wren-queue}}
{{libheader|Wren-queue}}
The above module contains a PriorityQueue class. Unlike some other languages here, the higher the number, the higher the priority. So the 'Make tea' task has the highest priority and, thankfully, the cat has a good chance of being fed!
The above module contains a PriorityQueue class. Unlike some other languages here, the higher the number, the higher the priority. So the 'Make tea' task has the highest priority and, thankfully, the cat has a good chance of being fed!
<syntaxhighlight lang=ecmascript>import "/queue" for PriorityQueue
<syntaxhighlight lang="ecmascript">import "/queue" for PriorityQueue


var tasks = PriorityQueue.new()
var tasks = PriorityQueue.new()
Line 7,422: Line 7,422:
The <code>'PUSH</code> method never needs to search down the levels. The efficiency bottleneck here is probably the implementation of <code>NCONC</code> (used for adding the new item to the end of the queue at the relevant level). A priority <i>stack</i>, with first in / last out at each priority level rather than first in / first out, would be faster.
The <code>'PUSH</code> method never needs to search down the levels. The efficiency bottleneck here is probably the implementation of <code>NCONC</code> (used for adding the new item to the end of the queue at the relevant level). A priority <i>stack</i>, with first in / last out at each priority level rather than first in / first out, would be faster.


<syntaxhighlight lang=lisp>(define-class priority-queue
<syntaxhighlight lang="lisp">(define-class priority-queue
(instance-variables queue lowest-priority most-urgent) )
(instance-variables queue lowest-priority most-urgent) )


Line 7,459: Line 7,459:


The example uses strings, but the data items stored in the priority queue can be of any type (including the empty list—or even other priority queues).
The example uses strings, but the data items stored in the priority queue can be of any type (including the empty list—or even other priority queues).
<syntaxhighlight lang=lisp>(define pq (priority-queue 'new 5))
<syntaxhighlight lang="lisp">(define pq (priority-queue 'new 5))


(pq 'push "Clear drains" 3)
(pq 'push "Clear drains" 3)
Line 7,468: Line 7,468:
{{out}}
{{out}}
Items are popped beginning from the most urgent:
Items are popped beginning from the most urgent:
<syntaxhighlight lang=lisp>[1] (pq 'pop)
<syntaxhighlight lang="lisp">[1] (pq 'pop)


"Solve RC tasks"
"Solve RC tasks"
Line 7,475: Line 7,475:
"Tax return"</syntaxhighlight>
"Tax return"</syntaxhighlight>
Within each priority level, new items are pushed onto the end and popped from the beginning of the list (a queue is a first in / first out data structure):
Within each priority level, new items are pushed onto the end and popped from the beginning of the list (a queue is a first in / first out data structure):
<syntaxhighlight lang=lisp>[3] (pq 'push "Answer emails" 4)
<syntaxhighlight lang="lisp">[3] (pq 'push "Answer emails" 4)


("Feed cat" "Answer emails")</syntaxhighlight>
("Feed cat" "Answer emails")</syntaxhighlight>
Attempting to push with an invalid priority value returns the empty list, i.e. false:
Attempting to push with an invalid priority value returns the empty list, i.e. false:
<syntaxhighlight lang=lisp>[4] (pq 'push "Weed garden" 17)
<syntaxhighlight lang="lisp">[4] (pq 'push "Weed garden" 17)


()</syntaxhighlight>
()</syntaxhighlight>
<code>'EMPTYP</code> returns false if the priority queue is not empty:
<code>'EMPTYP</code> returns false if the priority queue is not empty:
<syntaxhighlight lang=lisp>[5] (pq 'emptyp)
<syntaxhighlight lang="lisp">[5] (pq 'emptyp)


()</syntaxhighlight>
()</syntaxhighlight>
<code>'PEEK</code> non-destructively returns the item that would be popped if you called <code>'POP</code>:
<code>'PEEK</code> non-destructively returns the item that would be popped if you called <code>'POP</code>:
<syntaxhighlight lang=lisp>[6] (pq 'peek)
<syntaxhighlight lang="lisp">[6] (pq 'peek)


"Clear drains"</syntaxhighlight>
"Clear drains"</syntaxhighlight>
If you want to examine a whole priority queue, the built-in <code>'SHOW</code> method allows you to do so:
If you want to examine a whole priority queue, the built-in <code>'SHOW</code> method allows you to do so:
<syntaxhighlight lang=scheme>[7] (pq 'show)
<syntaxhighlight lang="scheme">[7] (pq 'show)


Object is #<Object:PRIORITY-QUEUE #x4e2cba8>, Class is #<Class:PRIORITY-QUEUE #x4e254c8>
Object is #<Object:PRIORITY-QUEUE #x4e2cba8>, Class is #<Class:PRIORITY-QUEUE #x4e254c8>
Line 7,500: Line 7,500:
#<Object:PRIORITY-QUEUE #x4e2cba8></syntaxhighlight>
#<Object:PRIORITY-QUEUE #x4e2cba8></syntaxhighlight>
Once all the items have been popped, the priority queue is empty and <code>'EMPTYP</code> then returns true:
Once all the items have been popped, the priority queue is empty and <code>'EMPTYP</code> then returns true:
<syntaxhighlight lang=lisp>[8] (pq 'pop)
<syntaxhighlight lang="lisp">[8] (pq 'pop)


"Clear drains"
"Clear drains"
Line 7,516: Line 7,516:
#T</syntaxhighlight>
#T</syntaxhighlight>
Attempting to pop from an empty priority queue returns false:
Attempting to pop from an empty priority queue returns false:
<syntaxhighlight lang=lisp>[13] (pq 'pop)
<syntaxhighlight lang="lisp">[13] (pq 'pop)


()</syntaxhighlight>
()</syntaxhighlight>
Line 7,526: Line 7,526:
Save the following code as <code>priority_queue.zig</code>, and run the tests using <code>zig test priority_queue.zig</code>.
Save the following code as <code>priority_queue.zig</code>, and run the tests using <code>zig test priority_queue.zig</code>.


<syntaxhighlight lang=Zig>
<syntaxhighlight lang="zig">
const std = @import("std");
const std = @import("std");
const PriorityQueue = std.PriorityQueue;
const PriorityQueue = std.PriorityQueue;
Line 7,616: Line 7,616:
Sample output:
Sample output:


<syntaxhighlight lang=Zig>
<syntaxhighlight lang="zig">
$ zig test priority_queue.zig
$ zig test priority_queue.zig
Test [1/2] test "priority queue (max heap)"...
Test [1/2] test "priority queue (max heap)"...
Line 7,637: Line 7,637:
=={{header|zkl}}==
=={{header|zkl}}==
This solution uses a [hopefully small] fixed number of priorities, each of which has an unordered list of tasks. This allows O(1) insertions, O(p) for retrievals (p is the number of priorities).
This solution uses a [hopefully small] fixed number of priorities, each of which has an unordered list of tasks. This allows O(1) insertions, O(p) for retrievals (p is the number of priorities).
<syntaxhighlight lang=zkl>class PQ{
<syntaxhighlight lang="zkl">class PQ{
fcn init(numLevels=10){ // 0..numLevels, bigger # == lower priorty
fcn init(numLevels=10){ // 0..numLevels, bigger # == lower priorty
var [const] queue=(1).pump(numLevels+1,List.createLong(numLevels).write,L().copy);
var [const] queue=(1).pump(numLevels+1,List.createLong(numLevels).write,L().copy);
Line 7,657: Line 7,657:
fcn toString{ "PQ(%d) items".fmt(queue.reduce(fcn(sum,q){ sum+q.len() },0)) }
fcn toString{ "PQ(%d) items".fmt(queue.reduce(fcn(sum,q){ sum+q.len() },0)) }
}</syntaxhighlight>
}</syntaxhighlight>
<syntaxhighlight lang=zkl>pq:=PQ();
<syntaxhighlight lang="zkl">pq:=PQ();
foreach x in
foreach x in
(T("Clear drains",3, "Feed cat",4, "Make tea",5, "Solve RC tasks",1, "Tax return",2,
(T("Clear drains",3, "Feed cat",4, "Make tea",5, "Solve RC tasks",1, "Tax return",2,