Advertisement
Guest User

Untitled

a guest
Jan 19th, 2017
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.74 KB | None | 0 0
  1. using System.Collections.Generic;
  2. using System;
  3.  
  4. public sealed class BinaryHeap<T>
  5. {
  6. private readonly List<T> _elements;
  7.  
  8. private readonly Comparison<T> _compare;
  9.  
  10. /// <summary>
  11. /// The amount of elements in the heap
  12. /// </summary>
  13. public int Count => _elements.Count;
  14.  
  15. /// <summary>
  16. /// A read only list of elements
  17. /// </summary>
  18. public List<T> Elements => new List<T>(_elements);
  19.  
  20. /// <summary>
  21. /// Returns the method that dictates how elements are compared
  22. /// </summary>
  23. public Comparison<T> Compare => _compare;
  24.  
  25. /// <summary>
  26. /// Clears the heap of all elements
  27. /// </summary>
  28. public void Clear() { _elements.Clear(); }
  29.  
  30. /// <summary>
  31. /// Initialises a new BinaryHeap with the specified compare function.
  32. /// </summary>
  33. /// <param name="compare">A method used to compare elements</param>
  34. public BinaryHeap(Comparison<T> compare)
  35. {
  36. _compare = compare;
  37. _elements = new List<T>();
  38. }
  39.  
  40. /// <summary>
  41. /// Initialises a new BinaryHeap as a copy of the passed in heap
  42. /// </summary>
  43. /// <param name="heap">The heap to copy</param>
  44. public BinaryHeap(BinaryHeap<T> heap)
  45. {
  46. _elements = new List<T>(heap.Elements);
  47. _compare = heap.Compare;
  48. }
  49.  
  50. /// <summary>
  51. /// Extracts the root
  52. /// </summary>
  53. /// <returns>The topmost object of the heap</returns>
  54. public T Extract()
  55. {
  56. if (_elements.Count == 0) throw new InvalidOperationException("The heap contains no elements");
  57. T node = _elements[0];
  58.  
  59. if (_elements.Count <= 2)
  60. _elements.RemoveAt(0);
  61. else
  62. {
  63. _elements[0] = _elements[_elements.Count - 1];
  64. _elements.RemoveAt(_elements.Count - 1);
  65. BubbleDown(_elements[0]);
  66. }
  67.  
  68. return node;
  69. }
  70. /// <summary>
  71. /// Inserts an element onto the heap
  72. /// </summary>
  73. /// <param name="entry">The object to add</param>
  74. public void Insert(T entry)
  75. {
  76. _elements.Add(entry);
  77. if ((_elements.Count - 1) == 0)
  78. return;
  79.  
  80. BubbleUp(entry);
  81.  
  82. }
  83. /// <summary>
  84. /// Peeks at the topmost object of the heap
  85. /// </summary>
  86. /// <returns>The top most object of the heap</returns>
  87. public T Peek()
  88. {
  89. //If a heap doesn't have any elements throw an exception
  90. if (_elements.Count == 0)
  91. throw new InvalidOperationException("The heap contains no elements");
  92. return _elements[0];
  93. }
  94.  
  95. /// <summary>
  96. /// Should Element1 be swapped with Element2 based on our Compare Delegate
  97. /// </summary>
  98. /// <returns>true if it should, false if it should not</returns>
  99. private bool ShouldSwap(T element1, T element2)
  100. {
  101. var comparision = Compare(element1, element2);
  102. return comparision <= 0;
  103. }
  104.  
  105. /// <summary>
  106. /// Swaps Element1 with Element2
  107. /// </summary>
  108. private void Swap(T element1, T element2)
  109. {
  110. //Swap the first element with the second
  111. int indexOfSecond = _elements.IndexOf(element2);
  112. _elements[_elements.IndexOf(element1)] = element2;
  113. _elements[indexOfSecond] = element1;
  114.  
  115.  
  116. }
  117.  
  118. /// <summary>
  119. /// Bubbles the specified element down the heap until the heaps properties are restored
  120. /// </summary>
  121. /// <param name="element">The Element to bubble down</param>
  122. private void BubbleDown(T element)
  123. {
  124. int elementIndex = _elements.IndexOf(element), minElementIndex = 0;
  125.  
  126. while (true)
  127. {
  128. int childLeftIndex = 2 * elementIndex + 1;
  129.  
  130. //If the Child index exists outside the amount of elements in the heap then
  131. //the element is already at the bottom of the heap so we should break.
  132. if (childLeftIndex >= _elements.Count)
  133. break;
  134.  
  135. element = _elements[elementIndex];
  136. var childElement = _elements[childLeftIndex];
  137.  
  138. if (ShouldSwap(childElement, element))
  139. minElementIndex = childLeftIndex;
  140.  
  141. int childRightIndex = childLeftIndex + 1;
  142.  
  143. //If the right child exists it must be checked as well
  144. if (childRightIndex < _elements.Count)
  145. {
  146.  
  147. element = _elements[minElementIndex];
  148. childElement = _elements[childRightIndex];
  149.  
  150. if (ShouldSwap(childElement, element))
  151. minElementIndex = childRightIndex;
  152. }
  153.  
  154.  
  155. //If the minimum Element is still the original element of the loop
  156. //then the heap properties has been restored and we should break
  157. if (elementIndex == minElementIndex)
  158. break;
  159.  
  160. //Since our element is out of order and violating the heaps properties it should be swapped
  161. Swap(_elements[elementIndex], _elements[minElementIndex]);
  162.  
  163.  
  164. elementIndex = minElementIndex;
  165. }
  166.  
  167. }
  168. /// <summary>
  169. /// Bubbles an Element up the heap until the heaps properties are restored
  170. /// </summary>
  171. /// <param name="element">The element to bubble up</param>
  172. private void BubbleUp(T element)
  173. {
  174. int elementIndex = _elements.IndexOf(element);
  175.  
  176. while (elementIndex > 0)
  177. {
  178. int parentIndex = (elementIndex - 1) / 2;
  179.  
  180. T elementParent = _elements[parentIndex];
  181. if (ShouldSwap(element, elementParent))
  182. {
  183. Swap(element, elementParent);
  184. elementIndex = parentIndex;
  185. }
  186. else break;
  187. }
  188.  
  189. _elements[elementIndex] = element;
  190. }
  191. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement