Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- public class MinHeap<T>
- {
- private readonly List<T> _elements;
- public int Size => _elements.Count;
- public bool IsEmpty => Size == 0;
- private readonly Comparator _comparator;
- public delegate int Comparator(T a, T b);
- public MinHeap(Comparator comparator, ICollection<T> elements = null)
- {
- _comparator = comparator;
- _elements = new List<T>();
- if(elements != null)
- {
- for(int i = 0; i < elements.Count; i++)
- {
- Add(elements[i]);
- }
- }
- }
- private int GetLeftChildIndex(int i) => 2 * i + 1;
- private int GetRightChildIndex(int i) => GetLeftChildIndex(i) + 1;
- private int GetParentIndex(int i) => (i - 1) / 2;
- private bool HasLeftChild(int i) => GetLeftChildIndex(i) < Size;
- private bool HasRightChild(int i) => GetRightChildIndex(i) < Size;
- private bool IsRoot(int i) => i == 0;
- private T GetLeftChild(int i) => _elements[GetLeftChildIndex(i)];
- private T GetRightChild(int i) => _elements[GetRightChildIndex(i)];
- private T GetParent(int i) => _elements[GetParentIndex(i)];
- private T GetRoot() => IsEmpty ? default(T) : _elements[0];
- private void CheckEmpty()
- {
- if (IsEmpty) throw new IndexOutOfRangeException();
- }
- private void Swap(int ia, int ib)
- {
- T temp = _elements[ia];
- _elements[ia] = _elements[ib];
- _elements[ib] = temp;
- }
- public T Peek()
- {
- CheckEmpty();
- return GetRoot();
- }
- public T Pop()
- {
- CheckEmpty();
- T ret = Peek();
- Swap(0, Size - 1);
- _elements.RemoveAt(Size - 1);
- PushDown();
- return ret;
- }
- public void Add(T element)
- {
- _elements.Add(element);
- PushUp();
- }
- private void PushDown()
- {
- PushDown(0);
- }
- private void PushDown(int i)
- {
- if (!HasLeftChild(i)) return;
- int smallestIndex = GetLeftChildIndex(i);
- if (HasRightChild(i))
- {
- T left = GetLeftChild(i);
- T right = GetRightChild(i);
- //left larger than right?
- if (_comparator(left, right) == 1)
- {
- smallestIndex = GetRightChildIndex(i);
- }
- }
- var element = _elements[i];
- var smallest = _elements[smallestIndex];
- //smallest smaller than current?
- if (_comparator(smallest, element) == -1)
- {
- Swap(smallestIndex, i);
- }
- PushDown(smallestIndex);
- }
- private void PushUp()
- {
- CheckEmpty();
- PushUp(Size - 1);
- }
- private void PushUp(int i)
- {
- if (i == 0) return;
- var parent = GetParent(i);
- //current larger than parent?
- var element = _elements[i];
- if (_comparator(element, parent) == 1) return;
- int parentIndex = GetParentIndex(i);
- Swap(parentIndex, i);
- PushUp(parentIndex);
- }
- }
- public class HeapExample
- {
- public HeapExample()
- {
- new MinHeap<int>((a, b) => a.CompareTo(b));
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement