Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. by Raj Rao
  2. http://blog.aggregatedIntelligence.com
  3.  
  4. public enum PriorityQueueType
  5. {
  6.     MinHeap = -1,
  7.     MaxHeap = 1,
  8. }
  9.  
  10. public class PriorityQueue<T> where T : IComparable
  11. {
  12.     readonly PriorityQueueType _type;
  13.    
  14.     public PriorityQueue(PriorityQueueType type)
  15.     {
  16.         _type = type;
  17.     }
  18.  
  19.     private List<T> _heap = new List<T>();
  20.    
  21.     public void Enqueue(IEnumerable<T> items)
  22.     {
  23.         foreach(T item in items)
  24.         {
  25.             Enqueue(item);
  26.         }
  27.     }
  28.    
  29.     public void Enqueue(T item)
  30.     {
  31.         _heap.Add(item);
  32.         if (_heap.Count <= 1)
  33.             return;
  34.         BubbleUp(_heap.Count - 1);
  35.     }
  36.    
  37.     public T Dequeue()
  38.     {
  39.         if (_heap.Count <= 0)
  40.             throw new InvalidOperationException("Queue is empty");
  41.        
  42.         T topItem = _heap[0];
  43.         if (_heap.Count > 1)
  44.         {
  45.             Swap(0,_heap.Count - 1);//swap with lowest so that bubbledown will work
  46.             _heap.RemoveAt(_heap.Count - 1);
  47.             BubbleDown(0);
  48.         }
  49.         else
  50.         {
  51.             _heap.RemoveAt(0);
  52.         }
  53.         return topItem;
  54.     }
  55.    
  56.     public bool HasItems()
  57.     {
  58.         return _heap.Count > 0;
  59.     }
  60.    
  61.     private void Swap(int parentIndex, int childIndex)
  62.     {
  63.         //Console.WriteLine(String.Format("bubbling parent {0},({1}) with child {2},({3})", parentIndex,_heap[parentIndex], childIndex, _heap[childIndex]));
  64.         T temp = _heap[parentIndex];
  65.         _heap[parentIndex] = _heap[childIndex];
  66.         _heap[childIndex] = temp;
  67.     }
  68.    
  69.     public override string ToString()
  70.     {
  71.         StringBuilder sb = new StringBuilder();
  72.         foreach(T item in _heap)
  73.         {
  74.             if (sb.Length > 0)
  75.                 sb.Append(","+item);
  76.             else
  77.                 sb.Append(item);
  78.         }
  79.         return sb.ToString();
  80.     }
  81.    
  82.     private int GetParent(int childIndex)
  83.     {
  84.         int parent = (childIndex - 1) / 2;
  85.         return parent;
  86.     }
  87.    
  88.     private int GetRightChild(int parentIndex)
  89.     {
  90.         int childIndex = parentIndex * 2 + 2; //(right);
  91.         return childIndex;
  92.     }
  93.    
  94.     private int GetLeftChild(int parentIndex)
  95.     {
  96.         int childIndex = parentIndex * 2 + 1; //(left);
  97.         return childIndex;
  98.     }
  99.    
  100.     private void BubbleDown(int parentIndex)
  101.     {
  102.         int leftChildIndex = GetLeftChild(parentIndex);
  103.         int rightChildIndex = GetRightChild(parentIndex);
  104.            
  105.         int largestItemIndex = parentIndex;
  106.         if (leftChildIndex < _heap.Count && (_heap[leftChildIndex].CompareTo(_heap[parentIndex])* (int)_type) > 0)
  107.         {
  108.             largestItemIndex = leftChildIndex;
  109.         }
  110.         if (rightChildIndex < _heap.Count && _heap[rightChildIndex].CompareTo(_heap[largestItemIndex]) * (int)_type > 0)
  111.         {
  112.             largestItemIndex = rightChildIndex;
  113.         }
  114.         if (parentIndex != largestItemIndex)
  115.         {
  116.             Swap(parentIndex, largestItemIndex);
  117.             BubbleDown(largestItemIndex);
  118.         }
  119.     }
  120.    
  121.     private void BubbleUp(int childIndex)
  122.     {
  123.         int parentIndex = GetParent(childIndex);
  124.         if(childIndex != parentIndex && _heap[childIndex].CompareTo(_heap[parentIndex]) * (int)_type > 0)
  125.         {
  126.             Swap(parentIndex, childIndex);
  127.             BubbleUp(parentIndex);
  128.         }
  129.     }
  130. }
  131.  
  132. void TestHeap(List<int> list, PriorityQueueType type)
  133. {
  134.     PriorityQueue<int> pq = new PriorityQueue<int>(type);
  135.     pq.Enqueue(list);
  136.     //print the contents of the heap
  137.     Console.WriteLine(pq);
  138.     //now dequeue and print to make sure items come out in order
  139.     while(pq.HasItems())
  140.     {
  141.         Console.WriteLine(pq.Dequeue());
  142.     }
  143. }
  144.  
  145. void Main()
  146. {
  147.     int count = 8;
  148.     Random random = new Random();
  149.     List<int> list = new List<int>();
  150.     for(int i = 0; i < count; i++)
  151.     {
  152.         list.Add(random.Next(-1000,10000));
  153.     }
  154.     TestHeap(list, PriorityQueueType.MinHeap);
  155.     TestHeap(list, PriorityQueueType.MaxHeap);
  156. }
  157.