Skip to content

Commit 7413d36

Browse files
committed
Add project files.
1 parent 8f09b04 commit 7413d36

File tree

7 files changed

+721
-0
lines changed

7 files changed

+721
-0
lines changed

PriorityQueue.sln

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.31321.278
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PriorityQueues", "PriorityQueues\PriorityQueues.csproj", "{3A937D8F-6DAC-4C9C-9889-1FA39FC0609B}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{3A937D8F-6DAC-4C9C-9889-1FA39FC0609B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{3A937D8F-6DAC-4C9C-9889-1FA39FC0609B}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{3A937D8F-6DAC-4C9C-9889-1FA39FC0609B}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{3A937D8F-6DAC-4C9C-9889-1FA39FC0609B}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {4A2C6C1C-55D9-4651-9C88-570A58F56AF2}
24+
EndGlobalSection
25+
EndGlobal

PriorityQueues/IPriorityElement.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace PriorityQueues
2+
{
3+
public interface IPriorityElement
4+
{
5+
float Priority { get; }
6+
}
7+
}

PriorityQueues/IPriorityQueue.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace PriorityQueues
5+
{
6+
public interface IPriorityQueue<T> : IEnumerable<T> where T : IPriorityElement
7+
{
8+
/// <summary>
9+
/// Gets the number of elements contained in the queue
10+
/// </summary>
11+
int Count { get; }
12+
13+
/// <summary>
14+
/// Clear all elements from the queue
15+
/// </summary>
16+
void Clear();
17+
18+
/// <summary>
19+
/// Determines whether the queue contains the specified element
20+
/// </summary>
21+
/// <param name="element"></param>
22+
/// <exception cref="ArgumentNullException"></exception>
23+
/// <returns><see langword="true"/> if the queue contains the specified element, <see langword="false"/> otherwise</returns>
24+
bool Contains(T element);
25+
26+
/// <summary>
27+
/// Returns the element with the highest priority value and removes it from the queue
28+
/// </summary>
29+
/// <exception cref="InvalidOperationException"></exception>
30+
/// <returns>The element with the highest priority</returns>
31+
T Dequeue();
32+
33+
/// <summary>
34+
/// Inserts an element to the queue according to its priority value
35+
/// </summary>
36+
/// <exception cref="ArgumentNullException"></exception>
37+
/// <param name="element">The element to be added to the queue</param>
38+
void Enqueue(T element);
39+
40+
/// <summary>
41+
/// Determines if the queue contains no elements
42+
/// </summary>
43+
/// <returns><see langword="true"/> if the queue contains no elements, <see langword="false"/> otherwise</returns>
44+
bool IsEmpty();
45+
46+
/// <summary>
47+
/// Returns the element with the highest priority value without removing it from the queue
48+
/// </summary>
49+
/// <exception cref="InvalidOperationException"></exception>
50+
/// <returns>The element with the highest priority</returns>
51+
T Peek();
52+
53+
/// <summary>
54+
/// Removes an element from the queue
55+
/// </summary>
56+
/// <param name="element">Element to remove from queue; can be null</param>
57+
/// <returns><see langword="true"/> if the element is successfuly removed; otherwise, <see langword="false"/>. This method also returns false if the element is not found in the queue</returns>
58+
bool Remove(T element);
59+
}
60+
}
Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
6+
namespace PriorityQueues
7+
{
8+
public class MappedPriorityQueue<T> : IPriorityQueue<T> where T : IPriorityElement
9+
{
10+
#region Private fields
11+
private List<T> _heap;
12+
13+
private Dictionary<T, List<int>> _map;
14+
#endregion
15+
16+
#region Public properties
17+
/// <inheritdoc/>
18+
public int Count => _heap.Count;
19+
#endregion
20+
21+
#region Constructors
22+
/// <summary>
23+
/// Initializes a new instance of <see cref="PriorityQueue{T}"/> class that is empty and has the default initial capacity
24+
/// </summary>
25+
public MappedPriorityQueue()
26+
{
27+
_heap = new List<T>();
28+
29+
_map = new Dictionary<T, List<int>>();
30+
}
31+
32+
/// <summary>
33+
/// Initializes a new instance of <see cref="PriorityQueue{T}"/> class that is empty and has the specified initial capacity
34+
/// </summary>
35+
/// <param name="capacity">The number of elements the <see cref="PriorityQueue{T}"/> can initially store</param>
36+
public MappedPriorityQueue(int capacity)
37+
{
38+
_heap = new List<T>(capacity);
39+
40+
_map = new Dictionary<T, List<int>>(capacity);
41+
}
42+
43+
/// <summary>
44+
/// Initializes a new instance of <see cref="PriorityQueue{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="PriorityQueue{T}"/></param>
47+
public MappedPriorityQueue(IEnumerable<T> collection)
48+
{
49+
_heap = new List<T>(collection.Count());
50+
51+
_map = new Dictionary<T, List<int>>();
52+
53+
int i = 0;
54+
foreach (var elem in collection)
55+
{
56+
_heap.Add(elem);
57+
58+
MapAdd(elem, i++);
59+
}
60+
61+
// heapify process
62+
for (int j = Math.Max(0, (_heap.Count / 2) - 1); j >= 0; j--)
63+
{
64+
Sink(i);
65+
}
66+
}
67+
#endregion
68+
69+
#region Public methods
70+
/// <inheritdoc/>
71+
public void Clear()
72+
{
73+
_heap.Clear();
74+
75+
_map.Clear();
76+
}
77+
78+
/// <inheritdoc/>
79+
public bool Contains(T element)
80+
{
81+
if (element == null)
82+
{
83+
throw new ArgumentNullException("element");
84+
}
85+
86+
// lookup the key in the dictionary
87+
return _map.ContainsKey(element);
88+
}
89+
90+
/// <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)
98+
{
99+
if (element == null)
100+
{
101+
throw new ArgumentNullException("element");
102+
}
103+
104+
_heap.Add(element);
105+
106+
MapAdd(element, _heap.Count - 1);
107+
108+
Swim(_heap.Count - 1);
109+
}
110+
111+
/// <inheritdoc/>
112+
public bool IsEmpty()
113+
{
114+
return Count == 0;
115+
}
116+
117+
/// <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)
125+
{
126+
if (element == null)
127+
{
128+
return false;
129+
}
130+
131+
int index = MapGet(element);
132+
if (index != -1)
133+
{
134+
RemoveAt(index);
135+
}
136+
return index != -1;
137+
}
138+
#endregion
139+
140+
#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)
203+
{
204+
T i_elem = _heap[i];
205+
T j_elem = _heap[j];
206+
207+
_heap[i] = j_elem;
208+
_heap[j] = i_elem;
209+
210+
MapSwap(i_elem, j_elem, i, j);
211+
}
212+
213+
private T RemoveAt(int index)
214+
{
215+
if (index < 0 || index > Count - 1)
216+
{
217+
throw new ArgumentOutOfRangeException("index", index, string.Empty);
218+
}
219+
220+
T removedElem = _heap[index];
221+
222+
Swap(index, Count - 1);
223+
224+
_heap.RemoveAt(Count - 1);
225+
226+
MapRemove(removedElem, Count - 1);
227+
228+
if (IsEmpty())
229+
{
230+
return removedElem;
231+
}
232+
233+
T elem = _heap[index];
234+
Sink(index);
235+
if (_heap[index].Equals(elem))
236+
{
237+
Swim(index);
238+
}
239+
240+
return removedElem;
241+
}
242+
243+
private void MapAdd(T value, int index)
244+
{
245+
if (!_map.ContainsKey(value))
246+
{
247+
_map[value] = new List<int>() { index };
248+
}
249+
else
250+
{
251+
_map[value].Add(index);
252+
}
253+
}
254+
255+
private void MapRemove(T value, int index)
256+
{
257+
_map[value].Remove(index);
258+
if (_map[value].Count == 0)
259+
{
260+
_map.Remove(value);
261+
}
262+
}
263+
264+
private int MapGet(T value)
265+
{
266+
if (_map.ContainsKey(value))
267+
{
268+
return _map[value][0];
269+
}
270+
else
271+
{
272+
return -1;
273+
}
274+
}
275+
276+
private void MapSwap(T value1, T value2, int index1, int index2)
277+
{
278+
_map[value1].Remove(index1);
279+
_map[value2].Remove(index2);
280+
_map[value1].Add(index2);
281+
_map[value2].Add(index1);
282+
}
283+
#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
296+
}
297+
}

0 commit comments

Comments
 (0)