Skip to content

Commit 213a207

Browse files
committed
Updated implementations to use a user-defined comparer.
1 parent 7f1775c commit 213a207

File tree

5 files changed

+41
-163
lines changed

5 files changed

+41
-163
lines changed

PriorityQueues/BinaryHeapPriorityQueue.cs

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55

66
namespace PriorityQueues
77
{
8-
public class BinaryHeapPriorityQueue<T> : IPriorityQueue<T> where T : IPriorityElement
8+
public class BinaryHeapPriorityQueue<T> : IPriorityQueue<T>
99
{
1010
#region Private fields
11-
private List<T> _heap;
11+
protected List<T> _heap;
12+
protected readonly Comparison<T> _comparer;
1213
#endregion
1314

1415
#region Public properties
@@ -20,27 +21,30 @@ public class BinaryHeapPriorityQueue<T> : IPriorityQueue<T> where T : IPriorityE
2021
/// <summary>
2122
/// Initializes a new instance of <see cref="BinaryHeapPriorityQueue{T}"/> class that is empty and has the default initial capacity
2223
/// </summary>
23-
public BinaryHeapPriorityQueue()
24+
public BinaryHeapPriorityQueue(Comparison<T> comparer)
2425
{
2526
_heap = new List<T>();
27+
_comparer = comparer;
2628
}
2729

2830
/// <summary>
2931
/// Initializes a new instance of <see cref="BinaryHeapPriorityQueue{T}"/> class that is empty and has the specified initial capacity
3032
/// </summary>
3133
/// <param name="capacity">The number of elements the <see cref="BinaryHeapPriorityQueue{T}"/> can initially store</param>
32-
public BinaryHeapPriorityQueue(int capacity)
34+
public BinaryHeapPriorityQueue(int capacity, Comparison<T> comparer)
3335
{
3436
_heap = new List<T>(capacity);
37+
_comparer = comparer;
3538
}
3639

3740
/// <summary>
3841
/// Initializes a new instance of <see cref="BinaryHeapPriorityQueue{T}"/> class that contains elements copied from the specified collection, sorted by their priority value
3942
/// </summary>
4043
/// <param name="collection">The collection whose elements are copied to the <see cref="BinaryHeapPriorityQueue{T}"/></param>
41-
public BinaryHeapPriorityQueue(IEnumerable<T> collection)
44+
public BinaryHeapPriorityQueue(IEnumerable<T> collection, Comparison<T> comparer)
4245
{
4346
_heap = new List<T>(collection.Count());
47+
_comparer = comparer;
4448

4549
int i = 0;
4650
foreach (var elem in collection)
@@ -58,13 +62,13 @@ public BinaryHeapPriorityQueue(IEnumerable<T> collection)
5862

5963
#region Public methods
6064
/// <inheritdoc/>
61-
public void Clear()
65+
public virtual void Clear()
6266
{
6367
_heap.Clear();
6468
}
6569

6670
/// <inheritdoc/>
67-
public bool Contains(T element)
71+
public virtual bool Contains(T element)
6872
{
6973
if (element == null)
7074
{
@@ -83,13 +87,13 @@ public bool Contains(T element)
8387
}
8488

8589
/// <inheritdoc/>
86-
public T Dequeue()
90+
public virtual T Dequeue()
8791
{
8892
return IsEmpty() ? throw new InvalidOperationException("Queue is empty") : RemoveAt(0);
8993
}
9094

9195
/// <inheritdoc/>
92-
public void Enqueue(T element)
96+
public virtual void Enqueue(T element)
9397
{
9498
if (element == null)
9599
{
@@ -102,19 +106,19 @@ public void Enqueue(T element)
102106
}
103107

104108
/// <inheritdoc/>
105-
public bool IsEmpty()
109+
public virtual bool IsEmpty()
106110
{
107111
return Count == 0;
108112
}
109113

110114
/// <inheritdoc/>
111-
public T Peek()
115+
public virtual T Peek()
112116
{
113117
return IsEmpty() ? throw new InvalidOperationException("Queue is empty") : _heap[0];
114118
}
115119

116120
/// <inheritdoc/>
117-
public bool Remove(T element)
121+
public virtual bool Remove(T element)
118122
{
119123
if (element == null)
120124
{
@@ -134,7 +138,7 @@ public bool Remove(T element)
134138
#endregion
135139

136140
#region Private methods
137-
private bool IsHeapInvariantMaintained(int index)
141+
protected bool IsHeapInvariantMaintained(int index)
138142
{
139143
if (index >= Count)
140144
{
@@ -153,12 +157,13 @@ private bool IsHeapInvariantMaintained(int index)
153157

154158
return IsHeapInvariantMaintained(leftIndex) && IsHeapInvariantMaintained(rightIndex);
155159
}
156-
private bool Less(int i, int j)
160+
161+
protected bool Less(int i, int j)
157162
{
158-
return _heap[i].Priority <= _heap[j].Priority;
163+
return _comparer(_heap[i], _heap[j]) <= 0;
159164
}
160165

161-
private void Swim(int index)
166+
protected void Swim(int index)
162167
{
163168
int parentIndex = (index - 1) / 2;
164169

@@ -170,7 +175,7 @@ private void Swim(int index)
170175
}
171176
}
172177

173-
private void Sink(int index)
178+
protected void Sink(int index)
174179
{
175180
while (true)
176181
{
@@ -193,7 +198,7 @@ private void Sink(int index)
193198
}
194199
}
195200

196-
private void Swap(int i, int j)
201+
protected virtual void Swap(int i, int j)
197202
{
198203
T i_elem = _heap[i];
199204
T j_elem = _heap[j];
@@ -202,7 +207,7 @@ private void Swap(int i, int j)
202207
_heap[j] = i_elem;
203208
}
204209

205-
private T RemoveAt(int index)
210+
protected virtual T RemoveAt(int index)
206211
{
207212
if (index < 0 || index > Count - 1)
208213
{

PriorityQueues/IPriorityElement.cs

Lines changed: 0 additions & 7 deletions
This file was deleted.

PriorityQueues/IPriorityQueue.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace PriorityQueues
55
{
6-
public interface IPriorityQueue<T> : IEnumerable<T> where T : IPriorityElement
6+
public interface IPriorityQueue<T> : IEnumerable<T>
77
{
88
/// <summary>
99
/// Gets the number of elements contained in the queue
Lines changed: 15 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,30 @@
11
using System;
2-
using System.Collections;
32
using System.Collections.Generic;
4-
using System.Linq;
53

64
namespace PriorityQueues
75
{
8-
public class MappedBinaryHeapPriorityQueue<T> : IPriorityQueue<T> where T : IPriorityElement
6+
public class MappedBinaryHeapPriorityQueue<T> : BinaryHeapPriorityQueue<T>
97
{
108
#region Private fields
11-
private List<T> _heap;
12-
139
private Dictionary<T, List<int>> _map;
1410
#endregion
1511

16-
#region Public properties
17-
/// <inheritdoc/>
18-
public int Count => _heap.Count;
19-
#endregion
20-
2112
#region Constructors
22-
/// <summary>
23-
/// Initializes a new instance of <see cref="MappedBinaryHeapPriorityQueue{T}"/> class that is empty and has the default initial capacity
24-
/// </summary>
25-
public MappedBinaryHeapPriorityQueue()
13+
/// <inheritdoc/>
14+
public MappedBinaryHeapPriorityQueue(Comparison<T> comparer) : base(comparer)
2615
{
27-
_heap = new List<T>();
28-
2916
_map = new Dictionary<T, List<int>>();
3017
}
3118

32-
/// <summary>
33-
/// Initializes a new instance of <see cref="MappedBinaryHeapPriorityQueue{T}"/> class that is empty and has the specified initial capacity
34-
/// </summary>
35-
/// <param name="capacity">The number of elements the <see cref="MappedBinaryHeapPriorityQueue{T}"/> can initially store</param>
36-
public MappedBinaryHeapPriorityQueue(int capacity)
19+
/// <inheritdoc/>
20+
public MappedBinaryHeapPriorityQueue(int capacity, Comparison<T> comparer) : base(capacity, comparer)
3721
{
38-
_heap = new List<T>(capacity);
39-
4022
_map = new Dictionary<T, List<int>>(capacity);
4123
}
4224

43-
/// <summary>
44-
/// Initializes a new instance of <see cref="MappedBinaryHeapPriorityQueue{T}"/> class that contains elements copied from the specified collection, sorted by their priority value
45-
/// </summary>
46-
/// <param name="collection">The collection whose elements are copied to the <see cref="MappedBinaryHeapPriorityQueue{T}"/></param>
47-
public MappedBinaryHeapPriorityQueue(IEnumerable<T> collection)
25+
/// <inheritdoc/>
26+
public MappedBinaryHeapPriorityQueue(IEnumerable<T> collection, Comparison<T> comparer) : base(comparer)
4827
{
49-
_heap = new List<T>(collection.Count());
50-
5128
_map = new Dictionary<T, List<int>>();
5229

5330
int i = 0;
@@ -68,15 +45,15 @@ public MappedBinaryHeapPriorityQueue(IEnumerable<T> collection)
6845

6946
#region Public methods
7047
/// <inheritdoc/>
71-
public void Clear()
48+
public override void Clear()
7249
{
73-
_heap.Clear();
50+
base.Clear();
7451

7552
_map.Clear();
7653
}
7754

7855
/// <inheritdoc/>
79-
public bool Contains(T element)
56+
public override bool Contains(T element)
8057
{
8158
if (element == null)
8259
{
@@ -88,40 +65,15 @@ public bool Contains(T element)
8865
}
8966

9067
/// <inheritdoc/>
91-
public T Dequeue()
92-
{
93-
return IsEmpty() ? throw new InvalidOperationException("Queue is empty") : RemoveAt(0);
94-
}
95-
96-
/// <inheritdoc/>
97-
public void Enqueue(T element)
68+
public override void Enqueue(T element)
9869
{
99-
if (element == null)
100-
{
101-
throw new ArgumentNullException("element");
102-
}
103-
104-
_heap.Add(element);
70+
base.Enqueue(element);
10571

10672
MapAdd(element, _heap.Count - 1);
107-
108-
Swim(_heap.Count - 1);
109-
}
110-
111-
/// <inheritdoc/>
112-
public bool IsEmpty()
113-
{
114-
return Count == 0;
11573
}
11674

11775
/// <inheritdoc/>
118-
public T Peek()
119-
{
120-
return IsEmpty() ? throw new InvalidOperationException("Queue is empty") : _heap[0];
121-
}
122-
123-
/// <inheritdoc/>
124-
public bool Remove(T element)
76+
public override bool Remove(T element)
12577
{
12678
if (element == null)
12779
{
@@ -138,68 +90,7 @@ public bool Remove(T element)
13890
#endregion
13991

14092
#region Private methods
141-
private bool IsHeapInvariantMaintained(int index)
142-
{
143-
if (index >= Count)
144-
{
145-
return true;
146-
}
147-
148-
int leftIndex = 2 * index + 1;
149-
int rightIndex = 2 * index + 2;
150-
151-
if (leftIndex < Count && !Less(index, leftIndex))
152-
{
153-
return false;
154-
}
155-
if (rightIndex < Count && !Less(index, rightIndex))
156-
{
157-
return false;
158-
}
159-
160-
return IsHeapInvariantMaintained(leftIndex) && IsHeapInvariantMaintained(rightIndex);
161-
}
162-
private bool Less(int i, int j)
163-
{
164-
return _heap[i].Priority <= _heap[j].Priority;
165-
}
166-
167-
private void Swim(int index)
168-
{
169-
int parentIndex = (index - 1) / 2;
170-
171-
while (index > 0 && Less(index, parentIndex))
172-
{
173-
Swap(parentIndex, index);
174-
index = parentIndex;
175-
parentIndex = (index - 1) / 2;
176-
}
177-
}
178-
179-
private void Sink(int index)
180-
{
181-
while (true)
182-
{
183-
int leftChildIndex = 2 * index + 1;
184-
int rightChildIndex = 2 * index + 2;
185-
int smallerNodeIndex = leftChildIndex;
186-
if (rightChildIndex < Count && Less(rightChildIndex, leftChildIndex))
187-
{
188-
smallerNodeIndex = rightChildIndex;
189-
}
190-
191-
// stop if we're outside bounds or we cannot sink anymore
192-
if (leftChildIndex >= Count || Less(index, smallerNodeIndex))
193-
{
194-
break;
195-
}
196-
197-
Swap(smallerNodeIndex, index);
198-
index = smallerNodeIndex;
199-
}
200-
}
201-
202-
private void Swap(int i, int j)
93+
protected override void Swap(int i, int j)
20394
{
20495
T i_elem = _heap[i];
20596
T j_elem = _heap[j];
@@ -210,7 +101,7 @@ private void Swap(int i, int j)
210101
MapSwap(i_elem, j_elem, i, j);
211102
}
212103

213-
private T RemoveAt(int index)
104+
protected override T RemoveAt(int index)
214105
{
215106
if (index < 0 || index > Count - 1)
216107
{
@@ -281,17 +172,5 @@ private void MapSwap(T value1, T value2, int index1, int index2)
281172
_map[value2].Add(index1);
282173
}
283174
#endregion
284-
285-
#region IEnumerable interface implementation
286-
public IEnumerator<T> GetEnumerator()
287-
{
288-
return ((IEnumerable<T>)_heap).GetEnumerator();
289-
}
290-
291-
IEnumerator IEnumerable.GetEnumerator()
292-
{
293-
return ((IEnumerable)_heap).GetEnumerator();
294-
}
295-
#endregion
296175
}
297176
}

0 commit comments

Comments
 (0)