using System.Text;
namespace System.Collections.Generic
{
///
/// Generic class for priority queue, it is based on a limited sorted array
///
/// Type of data object, must implement IComparable interface
/// Lower weights in queue has higher priority
class PriorityQueue
{
///
/// Sorted list of objects, acts like a binary tree
///
private List Queue = null;
///
/// Returns count of elements in queue
///
public int Count
{
get { return Queue.Count; }
}
///
/// Public constructor
///
/// Maximum size of queue
/// Throws when TObj does not implement IComparable interface
public PriorityQueue(int _queueSize)
{
if (typeof(TObj).GetInterface("IComparable") == null)
throw new Exception("PriorityQueue: Templated class " + typeof(TObj) + " does not implement IComparable.");
Queue = new List(_queueSize);
}
public override string ToString()
{
StringBuilder result = new StringBuilder();
for (int i = this.Count-1; i >= 0; i--)
{
if (i < this.Count-1)
result.Append(',');
result.Append(Queue[i]);
}
return result.ToString();
}
///
/// Clears all elements in the queue
///
public void Clear()
{
Queue.Clear();
}
///
/// Inserts an element in the queue, in the proper position according with weight
///
/// Object to enqueue, ignores if it is null
public void Enqueue(TObj _obj)
{
if (_obj == null)
return;
if (Queue.Count == 0) // Fast special case for empty queue
{
Queue.Add(_obj);
return;
}
// BinarySearch for element or best position
int posNew = Queue.BinarySearch(_obj);
// Inserts element in proper sorted position
if (posNew >= 0) // Similar element exists on queue, inserts new before
Queue.Insert(posNew, _obj);
else
{
posNew = ~posNew; // Binary invertion, as specified in BinarySearch() method help
if (posNew == Queue.Count)
Queue.Add(_obj);
else
Queue.Insert(posNew, _obj);
}
}
///
/// Extracts element from start of the queue
///
/// Reference to enqueued object, null if queue is empty
public TObj Dequeue()
{
if (Queue.Count == 0)
return default(TObj);
TObj _obj = Queue[0];
Queue.RemoveAt(0);
return _obj;
}
///
/// Returns a reference to element from start of queue, without removing it
///
/// Reference to enqueued object, null if queue is empty
public TObj Root()
{
if (Queue.Count == 0)
return default(TObj);
return Queue[0];
}
}
}