Skip to content

Commit 3ed0b5e

Browse files
ClémentClément
authored andcommitted
Improving PQueue implementation w/ heap.
1 parent ba99902 commit 3ed0b5e

3 files changed

Lines changed: 194 additions & 180 deletions

File tree

source/code/projects/PQueue_heap/PQueue/PQueue.cs

Lines changed: 162 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -4,193 +4,180 @@
44
public class PQueue<TPriority, TValue>
55
where TPriority : IComparable<TPriority>
66
{
7-
class Cell
8-
{
9-
public TPriority Priority { get; set; }
10-
public TValue Value { get; set; }
7+
class Cell
8+
{
9+
public TPriority Priority { get; set; }
10+
public TValue Value { get; set; }
11+
12+
public Cell(TPriority priorityP, TValue valueP)
13+
{
14+
Priority = priorityP;
15+
Value = valueP;
16+
}
17+
18+
public override string ToString()
19+
{
20+
return Value + " (priority: " + Priority + ")";
21+
}
22+
}
23+
24+
private Cell[] mArray;
1125

12-
public Cell(TPriority priorityP, TValue valueP)
26+
// Number of items in queue.
27+
private int count = 0;
28+
29+
public PQueue(int size = 100)
1330
{
14-
Priority = priorityP;
15-
Value = valueP;
31+
if (size < 10)
32+
size = 10;
33+
mArray = new Cell[size];
1634
}
1735

18-
public override string ToString()
36+
public bool IsEmpty()
1937
{
20-
return Value + " (priority: " + Priority + ")";
38+
return count == 0;
2139
}
22-
}
23-
24-
private Cell[] mArray;
25-
26-
// Number of items in queue.
27-
private int count = 0;
28-
29-
public PQueue(int size = 100)
30-
{
31-
if (size < 10)
32-
size = 10;
33-
mArray = new Cell[size];
34-
}
35-
36-
public bool IsEmpty()
37-
{
38-
return count == 0;
39-
}
40-
41-
public bool IsFull()
42-
{
43-
return (count == mArray.Length - 1);
44-
}
45-
46-
public void Clear()
47-
{
48-
count = 0;
49-
}
50-
51-
public TValue Peek()
52-
{
53-
if (IsEmpty())
54-
throw new ApplicationException(
55-
"Queue is empty, no most urgent value."
56-
);
57-
return mArray[1].Value;
58-
}
59-
60-
public void Add(TPriority priorityP, TValue valueP)
61-
{
62-
if (IsFull())
63-
throw new ApplicationException(
64-
"Queue is full, cannot add "
65-
+ valueP
66-
+ " with priority "
67-
+ priorityP
68-
+ "."
69-
);
70-
71-
// Otherwise, we will be able to add an element,
72-
// so count must increment.
73-
count++;
74-
// We now look for a place to insert the value.
75-
int hole = count;
76-
// As long as hole > 1 and priorityP is less than
77-
// the priority at hole / 2…
78-
while (
79-
hole > 1
80-
&& priorityP.CompareTo(mArray[hole / 2].Priority) < 0
81-
)
40+
41+
public bool IsFull()
8242
{
83-
mArray[hole] = mArray[hole / 2];
84-
hole /= 2;
85-
// We divide hole by 2
86-
// and move the data at hole / 2 at hole.
43+
return (count == mArray.Length - 1);
8744
}
88-
// Once this is done, we can insert the new value.
89-
mArray[hole] = new Cell(priorityP, valueP);
90-
}
91-
92-
public TValue Extract()
93-
{
94-
if (IsEmpty())
95-
throw new ApplicationException(
96-
"Queue is empty, cannot extract from it."
97-
);
98-
99-
// Save the data to be returned.
100-
TValue cellValue = mArray[1].Value;
101-
102-
// Move the "rightmost" cell from the
103-
// last level to the root.
104-
mArray[1] = mArray[count];
105-
// We have one less element now.
106-
count--;
107-
108-
// Move the lowest child up until we've found the right spot
109-
// for the cell moved from the last level to the root.
110-
PercolateDown(1);
111-
return cellValue;
112-
}
113-
114-
private void PercolateDown(int indexP)
115-
{
116-
// "PercolateDown", starting at
117-
// indexP.
118-
int child;
119-
// Save the hole's cell.
120-
Cell cellValue = mArray[indexP];
121-
122-
bool found = false;
123-
// Keep going down the tree until the last level
124-
while (indexP * 2 <= count && !found)
45+
46+
public void Clear()
12547
{
126-
child = indexP * 2; // get right child
127-
// check right and left child and put lowest one in the child variable
128-
if (
129-
child != count
130-
&& mArray[child + 1]
131-
.Priority.CompareTo(mArray[child].Priority) < 0
132-
)
133-
{
134-
child++;
135-
}
136-
// put lowest child in hole
137-
if (
138-
mArray[child].Priority.CompareTo(cellValue.Priority)
139-
< 0
140-
)
141-
{
142-
mArray[indexP] = mArray[child];
143-
}
144-
else
145-
{
146-
found = true;
147-
}
148-
// If we are not done,
149-
// we update the value for indexP.
150-
if (!found)
151-
{
152-
indexP = child;
153-
}
48+
count = 0;
15449
}
155-
// found right spot of hole's original value, put it back into tree
156-
mArray[indexP] = cellValue;
157-
}
158-
159-
/// <summary>
160-
/// Assumes all but last item in array is in correct order
161-
/// Shifts last item in array into correct location based on priority
162-
/// </summary>
163-
public void BuildHeap()
164-
{
165-
for (int i = count / 2; i > 0; i--)
166-
PercolateDown(i);
167-
}
168-
169-
public override string ToString()
170-
{
171-
string returned = "";
172-
for (int i = 1; i <= count; i++)
50+
51+
public TValue Peek()
17352
{
174-
returned += mArray[i].ToString() + "; ";
53+
if (IsEmpty())
54+
throw new ApplicationException(
55+
"Queue is empty, no most urgent value."
56+
);
57+
return mArray[1].Value;
17558
}
176-
return returned;
177-
}
178-
179-
// return string with contents of array in order (e.g. left child, parent, right child)
180-
public string InOrder()
181-
{
182-
return InOrder(1);
183-
}
184-
185-
private string InOrder(int position)
186-
{
187-
string returned = "";
188-
if (position <= count)
59+
60+
public void Add(TPriority priorityP, TValue valueP)
61+
{
62+
if (IsFull())
63+
throw new ApplicationException(
64+
"Queue is full, cannot add "
65+
+ valueP
66+
+ " with priority "
67+
+ priorityP
68+
+ "."
69+
);
70+
71+
// Otherwise, we will be able to add an element,
72+
// so count must increment.
73+
count++;
74+
// We now look for a place to insert the value,
75+
// we call it (empty) "slot".
76+
int slot = count;
77+
// As long as slot > 1 and priorityP is less than
78+
// the priority at slot / 2…
79+
while (
80+
slot > 1
81+
&& priorityP.CompareTo(mArray[slot / 2].Priority) < 0
82+
)
83+
{
84+
mArray[slot] = mArray[slot / 2];
85+
slot /= 2;
86+
// We divide slot by 2
87+
// and move the data at slot / 2 at slot.
88+
}
89+
// Once this is done, we can insert the
90+
// new value in the slot.
91+
mArray[slot] = new Cell(priorityP, valueP);
92+
}
93+
94+
public TValue Extract()
95+
{
96+
if (IsEmpty())
97+
throw new ApplicationException(
98+
"Queue is empty, cannot extract from it."
99+
);
100+
101+
// Save the data to be returned.
102+
TValue cellValue = mArray[1].Value;
103+
104+
// Replace the root with the last element
105+
// on the last level.
106+
mArray[1] = mArray[count];
107+
// We have one less element now.
108+
count--;
109+
110+
// Move the lowest child up until we've found the right spot
111+
// for the cell moved from the last level to the root.
112+
PercolateDown(1);
113+
return cellValue;
114+
}
115+
116+
private void PercolateDown(int indexP)
117+
{
118+
// "PercolateDown", starting at
119+
// indexP.
120+
int child;
121+
// Save the slot's cell.
122+
Cell travellingCell = mArray[indexP];
123+
124+
bool found = false;
125+
// Keep going down the tree until the last level
126+
// or until we found the place where it belongs.
127+
while (indexP * 2 <= count && !found)
128+
{
129+
// Get the right child.
130+
child = indexP * 2;
131+
// Now, we check right and left child
132+
// and put lowest one in the child variable
133+
if (child != count)
134+
{ // If there is a left child…
135+
if (mArray[child + 1]
136+
.Priority.CompareTo(mArray[child].Priority) < 0)
137+
{
138+
// … and it has a lowest priority, use it.
139+
child++;
140+
}
141+
}
142+
143+
// At this point, we know that child
144+
// refers the child with the lowest
145+
// priority.
146+
147+
// Now, we put the lowest child in slot
148+
// if its priority
149+
// is less than the priority of the cell
150+
// currently in the slot.
151+
if (
152+
mArray[child].Priority.CompareTo(travellingCell.Priority)
153+
< 0
154+
)
155+
{
156+
mArray[indexP] = mArray[child];
157+
}
158+
else
159+
{
160+
// Otherwise we are done.
161+
found = true;
162+
}
163+
// If we are not done,
164+
// we update the value for indexP.
165+
if (!found)
166+
{
167+
indexP = child;
168+
}
169+
}
170+
// found right spot of slot's original value, put it back into tree
171+
mArray[indexP] = travellingCell;
172+
}
173+
174+
public override string ToString()
189175
{
190-
returned += (position * 2) + "\t";
191-
returned += mArray[position].Value.ToString() + "\n ";
192-
returned += InOrder(position * 2 + 1) + "\t";
176+
string returned = "";
177+
for (int i = 1; i <= count; i++)
178+
{
179+
returned += mArray[i].ToString() + "; ";
180+
}
181+
return returned;
193182
}
194-
return returned;
195-
}
196183
}

source/code/projects/PQueue_heap/PQueue/Program.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,17 @@ static void Main(string[] args)
3434
PQueue<int, string> myQueue = new PQueue<int, string>(
3535
5
3636
);
37-
myQueue.Add(3, "Abdominal pain ");
38-
Console.WriteLine(myQueue);
39-
}
37+
myQueue.Add(3, "Abdominal pain");
38+
Console.WriteLine(myQueue);
39+
myQueue.Add(2, "Asthma attack");
40+
Console.WriteLine(myQueue);
41+
myQueue.Add(4, "Sore throat");
42+
Console.WriteLine(myQueue);
43+
myQueue.Add(3, "High fever with cough");
44+
Console.WriteLine(myQueue);
45+
myQueue.Add(1, "Unresponsive");
46+
Console.WriteLine(myQueue);
47+
myQueue.Add(1, "Cardiac arrest");
48+
Console.WriteLine(myQueue);
49+
}
4050
}

0 commit comments

Comments
 (0)