Advertisement
Venciity

PriorityQueue

Aug 20th, 2015
255
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.36 KB | None | 0 0
  1. namespace ImplementBinaryHeap
  2. {
  3.     using System;
  4.     using System.Collections;
  5.     using System.Collections.Generic;
  6.  
  7.     public class PriorityQueue<TPriority, TValue> : ICollection<KeyValuePair<TPriority, TValue>>
  8.     {
  9.         private List<KeyValuePair<TPriority, TValue>> baseHeap;
  10.         private IComparer<TPriority> comparer;
  11.  
  12.         public PriorityQueue()
  13.             : this(Comparer<TPriority>.Default)
  14.         {
  15.         }
  16.  
  17.         public PriorityQueue(int capacity)
  18.             : this(capacity, Comparer<TPriority>.Default)
  19.         {
  20.         }
  21.  
  22.         public PriorityQueue(int capacity, IComparer<TPriority> comparer)
  23.         {
  24.             if (comparer == null)
  25.             {
  26.                 throw new ArgumentNullException();
  27.             }
  28.  
  29.             this.baseHeap = new List<KeyValuePair<TPriority, TValue>>(capacity);
  30.             this.comparer = comparer;
  31.         }
  32.        
  33.         public PriorityQueue(IComparer<TPriority> comparer)
  34.         {
  35.             if (comparer == null)
  36.             {
  37.                 throw new ArgumentNullException();
  38.             }
  39.  
  40.             this.baseHeap = new List<KeyValuePair<TPriority, TValue>>();
  41.             this.comparer = comparer;
  42.         }
  43.  
  44.         public PriorityQueue(IEnumerable<KeyValuePair<TPriority, TValue>> data)
  45.             : this(data, Comparer<TPriority>.Default)
  46.         {
  47.         }
  48.  
  49.         public PriorityQueue(IEnumerable<KeyValuePair<TPriority, TValue>> data, IComparer<TPriority> comparer)
  50.         {
  51.             if (data == null || comparer == null)
  52.             {
  53.                 throw new ArgumentNullException();
  54.             }
  55.  
  56.             this.comparer = comparer;
  57.             this.baseHeap = new List<KeyValuePair<TPriority, TValue>>(data);
  58.  
  59.             for (int pos = (this.baseHeap.Count / 2) - 1; pos >= 0; pos--)
  60.             {
  61.                 this.HeapifyFromBeginningToEnd(pos);
  62.             }
  63.         }
  64.  
  65.         public int Count
  66.         {
  67.             get
  68.             {
  69.                 return this.baseHeap.Count;
  70.             }
  71.         }
  72.  
  73.         public bool IsEmpty
  74.         {
  75.             get
  76.             {
  77.                 return this.baseHeap.Count == 0;
  78.             }
  79.         }
  80.  
  81.         public bool IsReadOnly
  82.         {
  83.             get
  84.             {
  85.                 return false;
  86.             }
  87.         }
  88.  
  89.         public void CopyTo(KeyValuePair<TPriority, TValue>[] array, int arrayIndex)
  90.         {
  91.             this.baseHeap.CopyTo(array, arrayIndex);
  92.         }
  93.        
  94.         public void Enqueue(TPriority priority, TValue value)
  95.         {
  96.             this.Insert(priority, value);
  97.         }
  98.        
  99.         public KeyValuePair<TPriority, TValue> Dequeue()
  100.         {
  101.             if (!this.IsEmpty)
  102.             {
  103.                 KeyValuePair<TPriority, TValue> result = this.baseHeap[0];
  104.                 this.DeleteRoot();
  105.                 return result;
  106.             }
  107.             else
  108.             {
  109.                 throw new InvalidOperationException("Priority queue is empty");
  110.             }
  111.         }
  112.  
  113.         public TValue DequeueValue()
  114.         {
  115.             return this.Dequeue().Value;
  116.         }
  117.  
  118.         public KeyValuePair<TPriority, TValue> Peek()
  119.         {
  120.             if (this.IsEmpty)
  121.             {
  122.                 throw new InvalidOperationException("Priority queue is empty");
  123.             }
  124.  
  125.             return this.baseHeap[0];
  126.         }
  127.        
  128.         public TValue PeekValue()
  129.         {
  130.             return this.Peek().Value;
  131.         }
  132.        
  133.         public void Add(KeyValuePair<TPriority, TValue> item)
  134.         {
  135.             this.Enqueue(item.Key, item.Value);
  136.         }
  137.        
  138.         public void Clear()
  139.         {
  140.             this.baseHeap.Clear();
  141.         }
  142.  
  143.         public bool Contains(KeyValuePair<TPriority, TValue> item)
  144.         {
  145.             return this.baseHeap.Contains(item);
  146.         }
  147.  
  148.         public bool Remove(KeyValuePair<TPriority, TValue> item)
  149.         {
  150.             int elementIndex = this.baseHeap.IndexOf(item);
  151.             if (elementIndex < 0)
  152.             {
  153.                 return false;
  154.             }
  155.  
  156.             this.baseHeap[elementIndex] = this.baseHeap[this.baseHeap.Count - 1];
  157.             this.baseHeap.RemoveAt(this.baseHeap.Count - 1);
  158.  
  159.             int newPos = this.HeapifyFromEndToBeginning(elementIndex);
  160.             if (newPos == elementIndex)
  161.             {
  162.                 this.HeapifyFromBeginningToEnd(elementIndex);
  163.             }
  164.  
  165.             return true;
  166.         }
  167.  
  168.         public IEnumerator<KeyValuePair<TPriority, TValue>> GetEnumerator()
  169.         {
  170.             return this.baseHeap.GetEnumerator();
  171.         }
  172.        
  173.         IEnumerator IEnumerable.GetEnumerator()
  174.         {
  175.             return this.GetEnumerator();
  176.         }
  177.  
  178.         private void ExchangeElements(int firstIndex, int secondIndex)
  179.         {
  180.             KeyValuePair<TPriority, TValue> val = this.baseHeap[firstIndex];
  181.             this.baseHeap[firstIndex] = this.baseHeap[secondIndex];
  182.             this.baseHeap[secondIndex] = val;
  183.         }
  184.  
  185.         private void Insert(TPriority priority, TValue value)
  186.         {
  187.             KeyValuePair<TPriority, TValue> val = new KeyValuePair<TPriority, TValue>(priority, value);
  188.             this.baseHeap.Add(val);
  189.  
  190.             this.HeapifyFromEndToBeginning(this.baseHeap.Count - 1);
  191.         }
  192.  
  193.         private int HeapifyFromEndToBeginning(int pos)
  194.         {
  195.             if (pos >= this.baseHeap.Count)
  196.             {
  197.                 return -1;
  198.             }
  199.  
  200.             while (pos > 0)
  201.             {
  202.                 int parentPos = (pos - 1) / 2;
  203.                 if (this.comparer.Compare(this.baseHeap[parentPos].Key, this.baseHeap[pos].Key) <= 0)
  204.                 {
  205.                     break;
  206.                 }
  207.                 else
  208.                 {
  209.                     this.ExchangeElements(parentPos, pos);
  210.                     pos = parentPos;
  211.                 }
  212.             }
  213.  
  214.             return pos;
  215.         }
  216.  
  217.         private void DeleteRoot()
  218.         {
  219.             if (this.baseHeap.Count <= 1)
  220.             {
  221.                 this.baseHeap.Clear();
  222.                 return;
  223.             }
  224.  
  225.             this.baseHeap[0] = this.baseHeap[this.baseHeap.Count - 1];
  226.             this.baseHeap.RemoveAt(this.baseHeap.Count - 1);
  227.  
  228.             this.HeapifyFromBeginningToEnd(0);
  229.         }
  230.  
  231.         private void HeapifyFromBeginningToEnd(int pos)
  232.         {
  233.             if (pos >= this.baseHeap.Count)
  234.             {
  235.                 return;
  236.             }
  237.  
  238.             while (true)
  239.             {
  240.                 int smallest = pos;
  241.                 int left = (2 * pos) + 1;
  242.                 int right = (2 * pos) + 2;
  243.                 if (left < this.baseHeap.Count && this.comparer.Compare(this.baseHeap[smallest].Key, this.baseHeap[left].Key) > 0)
  244.                 {
  245.                     smallest = left;
  246.                 }
  247.  
  248.                 if (right < this.baseHeap.Count && this.comparer.Compare(this.baseHeap[smallest].Key, this.baseHeap[right].Key) > 0)
  249.                 {
  250.                     smallest = right;
  251.                 }
  252.  
  253.                 if (smallest != pos)
  254.                 {
  255.                     this.ExchangeElements(smallest, pos);
  256.                     pos = smallest;
  257.                 }
  258.                 else
  259.                 {
  260.                     break;
  261.                 }
  262.             }
  263.         }
  264.     }
  265. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement