/CatalogueRaisonne/CRShared/Source/Heap.cs

https://github.com/bretambrose/CatalogueRaisonnePublic · C# · 153 lines · 102 code · 25 blank · 26 comment · 13 complexity · d2b7256228cc865214102e49076ec631 MD5 · raw file

  1. /*
  2. Heap.cs
  3. (c) Copyright 2010-2011, Bret Ambrose (mailto:bretambrose@gmail.com).
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. using System;
  16. using System.Collections.Generic;
  17. namespace CRShared
  18. {
  19. public sealed class EmptyHeapException : Exception
  20. {
  21. public EmptyHeapException() {}
  22. public override string ToString()
  23. {
  24. return "Heap is empty. Cannot query elements in it.";
  25. }
  26. }
  27. public sealed class THeap< T > where T : IComparable< T >, new()
  28. {
  29. // Construction
  30. public THeap()
  31. {
  32. m_HeapVector = new List< T >();
  33. m_HeapVector.Add( new T() ); // dummy element in the 0th index
  34. }
  35. // Methods
  36. // Public interface
  37. public T Peek_Top()
  38. {
  39. if ( Empty )
  40. {
  41. throw new EmptyHeapException();
  42. }
  43. return m_HeapVector[ 1 ];
  44. }
  45. public T Pop_Top()
  46. {
  47. if ( Empty )
  48. {
  49. throw new EmptyHeapException();
  50. }
  51. T top_spot = m_HeapVector[ 1 ];
  52. m_HeapVector[ 1 ] = m_HeapVector[ Size ];
  53. m_HeapVector.RemoveAt( Size );
  54. if ( Size > 1 )
  55. {
  56. Heapify( 1 );
  57. }
  58. return top_spot;
  59. }
  60. public void Add( T element )
  61. {
  62. m_HeapVector.Add( element );
  63. int index = Size;
  64. while ( true )
  65. {
  66. int parent = ParentIndex( index );
  67. if ( parent <= 0 || m_HeapVector[ parent ].CompareTo( m_HeapVector[ index ] ) < 0 )
  68. {
  69. break;
  70. }
  71. T temp = m_HeapVector[ parent ];
  72. m_HeapVector[ parent ] = m_HeapVector[ index ];
  73. m_HeapVector[ index ] = temp;
  74. index = parent;
  75. }
  76. }
  77. // Private interface
  78. private void Heapify( int index )
  79. {
  80. int size = Size;
  81. while ( true )
  82. {
  83. int left = LeftIndex( index );
  84. int right = RightIndex( index );
  85. int smallest = index;
  86. if ( left <= size && m_HeapVector[ left ].CompareTo( m_HeapVector[ index ] ) < 0 )
  87. {
  88. smallest = left;
  89. }
  90. if ( right <= size && m_HeapVector[ right ].CompareTo( m_HeapVector[ smallest ] ) < 0 )
  91. {
  92. smallest = right;
  93. }
  94. if ( smallest == index )
  95. {
  96. break;
  97. }
  98. T temp = m_HeapVector[ smallest ];
  99. m_HeapVector[ smallest ] = m_HeapVector[ index ];
  100. m_HeapVector[ index ] = temp;
  101. index = smallest;
  102. }
  103. }
  104. private int ParentIndex( int index )
  105. {
  106. return index / 2;
  107. }
  108. private int LeftIndex( int index )
  109. {
  110. return index * 2;
  111. }
  112. private int RightIndex( int index )
  113. {
  114. return index * 2 + 1;
  115. }
  116. // Properties
  117. public bool Empty { get { return m_HeapVector.Count <= 1; } }
  118. public int Size { get { return m_HeapVector.Count - 1; } }
  119. // Fields
  120. private List< T > m_HeapVector = null;
  121. }
  122. }