Advertisement
teleias

Priority Queue

Jul 16th, 2019 (edited)
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.71 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3.  
  4. public class MinHeap<T>
  5. {
  6.     private readonly List<T> _elements;
  7.     public int Size => _elements.Count;
  8.     public bool IsEmpty => Size == 0;
  9.  
  10.     private readonly Comparator _comparator;
  11.     public delegate int Comparator(T a, T b);
  12.  
  13.     public MinHeap(Comparator comparator, ICollection<T> elements = null)
  14.     {
  15.         _comparator = comparator;
  16.         _elements = new List<T>();
  17.  
  18.  
  19.         if(elements != null)
  20.         {
  21.             for(int i = 0; i < elements.Count; i++)
  22.             {
  23.                 Add(elements[i]);
  24.             }
  25.         }
  26.     }
  27.     private int GetLeftChildIndex(int i) => 2 * i + 1;
  28.     private int GetRightChildIndex(int i) => GetLeftChildIndex(i) + 1;
  29.     private int GetParentIndex(int i) => (i - 1) / 2;
  30.  
  31.     private bool HasLeftChild(int i) => GetLeftChildIndex(i) < Size;
  32.     private bool HasRightChild(int i) => GetRightChildIndex(i) < Size;
  33.     private bool IsRoot(int i) => i == 0;
  34.  
  35.     private T GetLeftChild(int i) => _elements[GetLeftChildIndex(i)];
  36.     private T GetRightChild(int i) => _elements[GetRightChildIndex(i)];
  37.     private T GetParent(int i) => _elements[GetParentIndex(i)];
  38.     private T GetRoot() => IsEmpty ? default(T) : _elements[0];
  39.  
  40.     private void CheckEmpty()
  41.     {
  42.         if (IsEmpty) throw new IndexOutOfRangeException();
  43.     }
  44.  
  45.     private void Swap(int ia, int ib)
  46.     {
  47.         T temp = _elements[ia];
  48.         _elements[ia] = _elements[ib];
  49.         _elements[ib] = temp;
  50.     }
  51.  
  52.     public T Peek()
  53.     {
  54.         CheckEmpty();
  55.         return GetRoot();
  56.     }
  57.  
  58.     public T Pop()
  59.     {
  60.         CheckEmpty();
  61.  
  62.         T ret = Peek();
  63.         Swap(0, Size - 1);
  64.         _elements.RemoveAt(Size - 1);
  65.  
  66.         PushDown();
  67.         return ret;
  68.     }
  69.  
  70.     public void Add(T element)
  71.     {
  72.         _elements.Add(element);
  73.         PushUp();
  74.     }
  75.  
  76.     private void PushDown()
  77.     {
  78.         PushDown(0);
  79.     }
  80.     private void PushDown(int i)
  81.     {
  82.         if (!HasLeftChild(i)) return;
  83.  
  84.         int smallestIndex = GetLeftChildIndex(i);
  85.         if (HasRightChild(i))
  86.         {
  87.             T left = GetLeftChild(i);
  88.             T right = GetRightChild(i);
  89.             //left larger than right?
  90.             if (_comparator(left, right) == 1)
  91.             {
  92.                 smallestIndex = GetRightChildIndex(i);
  93.             }
  94.         }
  95.  
  96.         var element = _elements[i];
  97.         var smallest = _elements[smallestIndex];
  98.  
  99.         //smallest smaller than current?
  100.         if (_comparator(smallest, element) == -1)
  101.         {
  102.             Swap(smallestIndex, i);
  103.         }
  104.         PushDown(smallestIndex);
  105.     }
  106.  
  107.     private void PushUp()
  108.     {
  109.         CheckEmpty();
  110.         PushUp(Size - 1);
  111.     }
  112.     private void PushUp(int i)
  113.     {
  114.         if (i == 0) return;
  115.         var parent = GetParent(i);
  116.         //current larger than parent?
  117.         var element = _elements[i];
  118.  
  119.         if (_comparator(element, parent) == 1) return;
  120.         int parentIndex = GetParentIndex(i);
  121.         Swap(parentIndex, i);
  122.         PushUp(parentIndex);
  123.     }
  124. }
  125.  
  126. public class HeapExample
  127. {
  128.     public HeapExample()
  129.     {
  130.         new MinHeap<int>((a, b) => a.CompareTo(b));
  131.     }
  132. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement