1111import fj .data .fingertrees .FingerTree ;
1212
1313/**
14+ * A priority queue implementation backed by a {@link fj.data.fingertrees.FingerTree}. The finger tree nodes are annotated with type K, are combined using a monoid of K and both the key and value are stored in the leaf. Priorities of the same value are returned FIFO (first in, first out).
15+ *
1416 * Created by MarkPerry on 31 May 16.
1517 */
1618public class PriorityQueue <K , A > {
@@ -23,55 +25,94 @@ private PriorityQueue(Equal<K> e, FingerTree<K, P2<K, A>> ft) {
2325 ftree = ft ;
2426 }
2527
28+ /**
29+ * Creates a priority queue from a finger tree.
30+ */
2631 public static <K , A > PriorityQueue <K , A > priorityQueue (Equal <K > e , FingerTree <K , P2 <K , A >> ft ) {
2732 return new PriorityQueue <K , A >(e , ft );
2833 }
2934
35+ /**
36+ * Creates an empty priority queue.
37+ *
38+ * @param m A monoid to combine node annotations.
39+ * @param e A value to compare key equality.
40+ */
3041 public static <K , A > PriorityQueue <K , A > empty (Monoid <K > m , Equal <K > e ) {
3142 return priorityQueue (e , FingerTree .empty (m , (P2 <K , A > p ) -> p ._1 ()));
3243 }
3344
45+ /**
46+ * An empty priority queue with integer priorities.
47+ */
3448 public static <A > PriorityQueue <Integer , A > emptyInt () {
3549 return priorityQueue (Equal .intEqual , FingerTree .empty (Monoid .intMaxMonoid , (P2 <Integer , A > p ) -> p ._1 ()));
3650 }
3751
52+ /**
53+ * Maps the values in each node with function f.
54+ */
3855 public <B > PriorityQueue <K , B > map (F <A , B > f ) {
3956 return priorityQueue (equal ,
4057 ftree .map (p2 -> p2 .map2 (a -> f .f (a )),
4158 FingerTree .measured (ftree .measured ().monoid (), (P2 <K , B > p2 ) -> p2 ._1 ()))
4259 );
4360 }
4461
62+ /**
63+ * Filters nodes based on the value inside each node.
64+ */
4565 public PriorityQueue <K , A > filterValues (F <A , Boolean > f ) {
4666 return priorityQueue (equal , ftree .filter (p2 -> f .f (p2 ._2 ())));
4767 }
4868
69+ /**
70+ * Filters the nodes based on the annotation of each node.
71+ */
4972 public PriorityQueue <K , A > filterKeys (F <K , Boolean > f ) {
5073 return priorityQueue (equal , ftree .filter (p2 -> f .f (p2 ._1 ())));
5174 }
5275
76+ /**
77+ * Is the tree empty?
78+ */
5379 public boolean isEmpty () {
5480 return ftree .isEmpty ();
5581 }
5682
83+ /**
84+ * If the tree is not empty, returns the node with highest priority otherwise returns nothing.
85+ */
5786 public Option <P2 <K , A >> top () {
5887 K top = ftree .measure ();
5988 P2 <FingerTree <K , P2 <K , A >>, FingerTree <K , P2 <K , A >>> p = ftree .split (k -> equal .eq (top , k ));
6089 return p ._2 ().headOption ();
6190 }
6291
92+ /**
93+ * Adds a node with priority k and value a. This operation take O(1).
94+ */
6395 public PriorityQueue <K , A > enqueue (K k , A a ) {
6496 return priorityQueue (equal , ftree .snoc (P .p (k , a )));
6597 }
6698
99+ /**
100+ * Adds nodes using the list of products with priority k and value a. This operation takes O(list.length()).
101+ */
67102 public PriorityQueue <K , A > enqueue (List <P2 <K , A >> list ) {
68103 return list .foldLeft (pq -> p -> pq .enqueue (p ._1 (), p ._2 ()), this );
69104 }
70105
71- public boolean contains (final K k1 ) {
72- return !ftree .split (k2 -> equal .eq (k1 , k2 ))._2 ().isEmpty ();
106+ /**
107+ * Does the priority k exist already?
108+ */
109+ public boolean contains (final K k ) {
110+ return !ftree .split (k2 -> equal .eq (k , k2 ))._2 ().isEmpty ();
73111 }
74112
113+ /**
114+ * Adds nodes using the iterable of products with priority k and value a.
115+ */
75116 public PriorityQueue <K , A > enqueue (Iterable <P2 <K , A >> it ) {
76117 PriorityQueue <K , A > result = this ;
77118 for (P2 <K , A > p : it ) {
@@ -80,21 +121,33 @@ public PriorityQueue<K, A> enqueue(Iterable<P2<K, A>> it) {
80121 return result ;
81122 }
82123
124+ /**
125+ * Adds a node with priority k and value a. This operation take O(1).
126+ */
83127 public PriorityQueue <K , A > enqueue (P2 <K , A > p ) {
84128 return enqueue (p ._1 (), p ._2 ());
85129 }
86130
131+ /**
132+ * Removes the node with the highest priority.
133+ */
87134 public PriorityQueue <K , A > dequeue () {
88135 K top = ftree .measure ();
89136 P2 <FingerTree <K , P2 <K , A >>, FingerTree <K , P2 <K , A >>> p = ftree .split (k -> equal .eq (k , top ));
90137 FingerTree <K , P2 <K , A >> right = p ._2 ();
91138 return right .isEmpty () ? this : priorityQueue (equal , p ._1 ().append (right .tail ()));
92139 }
93140
141+ /**
142+ * Returns a tuple of the node with the highest priority and the rest of the priority queue.
143+ */
94144 public P2 <Option <P2 <K , A >>, PriorityQueue <K , A >> dequeueTop () {
95145 return P .p (top (), dequeue ());
96146 }
97147
148+ /**
149+ * Removes the top n elements with the highest priority.
150+ */
98151 public PriorityQueue <K , A > dequeue (int n ) {
99152 int i = n ;
100153 PriorityQueue <K , A > result = this ;
@@ -105,14 +158,23 @@ public PriorityQueue<K, A> dequeue(int n) {
105158 return result ;
106159 }
107160
161+ /**
162+ * Does the priority k have greater priority than the top of the queue?
163+ */
108164 public boolean isGreaterThan (Ord <K > ok , K k ) {
109165 return top ().map (p -> ok .isGreaterThan (k , p ._1 ())).orSome (true );
110166 }
111167
168+ /**
169+ * Returns a stream of products with priority k and value a.
170+ */
112171 public Stream <P2 <K , A >> toStream () {
113172 return top ().map (p -> Stream .cons (p , () -> dequeue ().toStream ())).orSome (() -> Stream .nil ());
114173 }
115174
175+ /**
176+ * Returns a list of products with priority k and value a.
177+ */
116178 public List <P2 <K , A >> toList () {
117179 return toStream ().toList ();
118180 }
0 commit comments