Skip to content

Commit 66fc314

Browse files
ClémentClément
authored andcommitted
Recording some additional pointers for priority queue.
1 parent 281d524 commit 66fc314

4 files changed

Lines changed: 202 additions & 4 deletions

File tree

source/code/projects/PQueue_array/PQueue/PQueue.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public void Add(TPriority priorityP, TValue valueP)
4141
}
4242
if (slot == -1)
4343
{
44-
throw new ApplicationException("Could not add the element.");
44+
throw new ApplicationException("Queue is full, cannot add " + valueP + " with priority " + priorityP + ".");
4545
}
4646
else
4747
{
@@ -100,11 +100,11 @@ public int MinPriority()
100100
return minI;
101101
}
102102

103-
public string Peek()
103+
public TValue Peek()
104104
{
105105
// Looking at the most urgent Cell
106106
// uses MinPriority.
107-
return mArray[MinPriority()].ToString();
107+
return mArray[MinPriority()].Value;
108108
}
109109

110110
public string Extract()
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
public class PQueue<TPriority, TValue> where TPriority : IComparable<TPriority>
5+
{
6+
7+
class Cell
8+
{
9+
public TPriority Priority { get; set; }
10+
public TValue Value { get; set; }
11+
public Cell(TPriority priorityP, TValue valueP)
12+
{
13+
Priority = priorityP;
14+
Value = valueP;
15+
}
16+
public override string ToString()
17+
{
18+
return Value + " (priority: " + Priority + ")";
19+
}
20+
}
21+
22+
private Cell[] mArray;
23+
// Number of items in queue.
24+
private int count = 0;
25+
26+
public PQueue(int size = 100)
27+
{
28+
if (size < 10)
29+
size = 10;
30+
mArray = new Cell[size];
31+
}
32+
33+
public bool IsEmpty()
34+
{
35+
return count == 0;
36+
}
37+
38+
public bool IsFull()
39+
{
40+
return (count == mArray.Length - 1);
41+
}
42+
43+
public void Clear()
44+
{
45+
count = 0;
46+
}
47+
48+
49+
public TValue Peek()
50+
{
51+
if (IsEmpty()) throw new ApplicationException("Queue is empty, no most urgent value.");
52+
return mArray[1].Value;
53+
}
54+
55+
public void Add(TPriority priorityP, TValue valueP)
56+
{
57+
if (IsFull()) throw new ApplicationException("Queue is full, cannot add " + valueP + " with priority " + priorityP + ".");
58+
59+
// Otherwise, we will be able to add an element,
60+
// so count must increment.
61+
count++;
62+
// We now look for a place to insert the value.
63+
int hole = count;
64+
// As long as hole > 1 and priorityP is less than
65+
// the priority at hole / 2…
66+
while(hole > 1 && priorityP.CompareTo(mArray[hole / 2].Priority) < 0)
67+
{
68+
mArray[hole] = mArray[hole / 2];
69+
hole /= 2;
70+
// We divide hole by 2
71+
// and move the data at hole / 2 at hole.
72+
}
73+
// Once this is done, we can insert the new value.
74+
mArray[hole] = new Cell(priorityP, aValue);
75+
}
76+
77+
public TValue Extract()
78+
{
79+
if (IsEmpty())
80+
throw new ApplicationException("Queue is empty, cannot extract from it.");
81+
82+
// Save the data to be returned.
83+
TValue value = mArray[1].Value;
84+
85+
// put the last item in the tree in the root
86+
mArray[1] = mArray[count];
87+
// We have one less element now
88+
count--;
89+
90+
// Move the lowest child up until we've found the right spot
91+
// for the item moved from the last level to the root.
92+
PercolateDown(1);
93+
94+
return value;
95+
}
96+
97+
private void PercolateDown(int hole)
98+
{
99+
int child;
100+
// save the hole's cell in a tmp spot
101+
Cell pTmp = mArray[hole];
102+
103+
// keep going down the tree until the last level
104+
for (; hole * 2 <= count; hole = child)
105+
{
106+
child = hole * 2; // get right child
107+
// check right and left child and put lowest one in the child variable
108+
if (child != count && mArray[child + 1].Priority.CompareTo(mArray[child].Priority) < 0)
109+
child++;
110+
// put lowest child in hole
111+
if (mArray[child].Priority.CompareTo(pTmp.Priority) < 0)
112+
{
113+
mArray[hole] = mArray[child];
114+
}
115+
else
116+
break;
117+
}
118+
// found right spot of hole's original value, put it back into tree
119+
mArray[hole] = pTmp;
120+
}
121+
122+
/// <summary>
123+
/// Assumes all but last item in array is in correct order
124+
/// Shifts last item in array into correct location based on priority
125+
/// </summary>
126+
public void BuildHeap()
127+
{
128+
for (int i = count / 2; i > 0; i--)
129+
PercolateDown(i);
130+
}
131+
132+
public override string ToString()
133+
{
134+
string returned = "";
135+
for (int i = 1; i <= count; i++)
136+
{
137+
returned += mArray[i].Value.ToString() + "; ";
138+
}
139+
return returned;
140+
}
141+
142+
// return string with contents of array in order (e.g. left child, parent, right child)
143+
public string InOrder()
144+
{
145+
return InOrder(1);
146+
}
147+
private string InOrder(int position)
148+
{
149+
string returned = "";
150+
if (position <= count)
151+
{
152+
returned += (position * 2) + "\t";
153+
returned += mArray[position].Value.ToString() + "\n ";
154+
returned += InOrder(position * 2 + 1) + "\t";
155+
}
156+
return returned;
157+
}
158+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System;
2+
3+
class Program
4+
{
5+
static void Main(string[] args)
6+
{
7+
PQueue<int, string> myQueue = new PQueue<int, string>(5);
8+
}
9+
}

source/lectures/data/priority_queue.md

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,38 @@ An implementation using lists would be very similar to the one using array, exce
5050

5151
### Using Heaps
5252

53-
A maximally efficient implementation of priority queues is given by [heaps](https://en.wikipedia.org/wiki/Heap_(data_structure)).
53+
A maximally efficient implementation of priority queues is given by [heaps](https://en.wikipedia.org/wiki/Heap_(data_structure)), which is
54+
55+
- A complete binary tree^[A complete binary tree is such that all levels are filled completely except the lowest level, which is filled from as left as possible.] (that we will represent in an array),
56+
– Such that the priority of every (non-root) node is less important than the priority of its parent.
57+
58+
Note that this is different from being a binary search tree.
59+
60+
```{download="./code/projects/PQueue_heap.zip"}
61+
!include code/projects/PQueue_heap/PQueue/PQueue.cs
62+
```
63+
64+
65+
<!--
66+
67+
- Index 0 is unused.
68+
- Most important will be at index 1.
69+
70+
Deleting consists in:
71+
- Remove node root,
72+
- Move right-most node in last row to root,
73+
- "Percolate down" to restore heap property
74+
75+
https://slideplayer.com/slide/17853217/
76+
77+
78+
https://courses.cs.washington.edu/courses/cse373/18su/files/slides/lecture-10.pdf
79+
https://courses.cs.washington.edu/courses/cse373/14sp/lecture9.pdf
80+
https://www.geeksforgeeks.org/dsa/priority-queue-using-linked-list/
81+
https://www.geeksforgeeks.org/dsa/priority-queue-using-array/
82+
https://en.wikipedia.org/wiki/Priority_queue
83+
84+
-->
5485

5586
<!--
5687

0 commit comments

Comments
 (0)