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]; } } }