by Raj Rao
http://blog.aggregatedIntelligence.com
public enum PriorityQueueType
{
MinHeap = -1,
MaxHeap = 1,
}
public class PriorityQueue<T> where T : IComparable
{
readonly PriorityQueueType _type;
public PriorityQueue(PriorityQueueType type)
{
_type = type;
}
private List<T> _heap = new List<T>();
public void Enqueue(IEnumerable<T> items)
{
foreach(T item in items)
{
Enqueue(item);
}
}
public void Enqueue(T item)
{
_heap.Add(item);
if (_heap.Count <= 1)
return;
BubbleUp(_heap.Count - 1);
}
public T Dequeue()
{
if (_heap.Count <= 0)
throw new InvalidOperationException("Queue is empty");
T topItem = _heap[0];
if (_heap.Count > 1)
{
Swap(0,_heap.Count - 1);//swap with lowest so that bubbledown will work
_heap.RemoveAt(_heap.Count - 1);
BubbleDown(0);
}
else
{
_heap.RemoveAt(0);
}
return topItem;
}
public bool HasItems()
{
return _heap.Count > 0;
}
private void Swap(int parentIndex, int childIndex)
{
//Console.WriteLine(String.Format("bubbling parent {0},({1}) with child {2},({3})", parentIndex,_heap[parentIndex], childIndex, _heap[childIndex]));
T temp = _heap[parentIndex];
_heap[parentIndex] = _heap[childIndex];
_heap[childIndex] = temp;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
foreach(T item in _heap)
{
if (sb.Length > 0)
sb.Append(","+item);
else
sb.Append(item);
}
return sb.ToString();
}
private int GetParent(int childIndex)
{
int parent = (childIndex - 1) / 2;
return parent;
}
private int GetRightChild(int parentIndex)
{
int childIndex = parentIndex * 2 + 2; //(right);
return childIndex;
}
private int GetLeftChild(int parentIndex)
{
int childIndex = parentIndex * 2 + 1; //(left);
return childIndex;
}
private void BubbleDown(int parentIndex)
{
int leftChildIndex = GetLeftChild(parentIndex);
int rightChildIndex = GetRightChild(parentIndex);
int largestItemIndex = parentIndex;
if (leftChildIndex < _heap.Count && (_heap[leftChildIndex].CompareTo(_heap[parentIndex])* (int)_type) > 0)
{
largestItemIndex = leftChildIndex;
}
if (rightChildIndex < _heap.Count && _heap[rightChildIndex].CompareTo(_heap[largestItemIndex]) * (int)_type > 0)
{
largestItemIndex = rightChildIndex;
}
if (parentIndex != largestItemIndex)
{
Swap(parentIndex, largestItemIndex);
BubbleDown(largestItemIndex);
}
}
private void BubbleUp(int childIndex)
{
int parentIndex = GetParent(childIndex);
if(childIndex != parentIndex && _heap[childIndex].CompareTo(_heap[parentIndex]) * (int)_type > 0)
{
Swap(parentIndex, childIndex);
BubbleUp(parentIndex);
}
}
}
void TestHeap(List<int> list, PriorityQueueType type)
{
PriorityQueue<int> pq = new PriorityQueue<int>(type);
pq.Enqueue(list);
//print the contents of the heap
Console.WriteLine(pq);
//now dequeue and print to make sure items come out in order
while(pq.HasItems())
{
Console.WriteLine(pq.Dequeue());
}
}
void Main()
{
int count = 8;
Random random = new Random();
List<int> list = new List<int>();
for(int i = 0; i < count; i++)
{
list.Add(random.Next(-1000,10000));
}
TestHeap(list, PriorityQueueType.MinHeap);
TestHeap(list, PriorityQueueType.MaxHeap);
}