heap_vs.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. ////////////////////////////////////////////////////////////////////////////////////////
  2. // RAVEN STANDARD TEMPLATE LIBRARY
  3. // (c) 2002 Activision
  4. //
  5. //
  6. // Heap
  7. // ------
  8. //
  9. //
  10. //
  11. //
  12. // TODO:
  13. //
  14. //
  15. // NOTES:
  16. //
  17. //
  18. ////////////////////////////////////////////////////////////////////////////////////////
  19. #if !defined(RATL_HEAP_VS_INC)
  20. #define RATL_HEAP_VS_INC
  21. ////////////////////////////////////////////////////////////////////////////////////////
  22. // Includes
  23. ////////////////////////////////////////////////////////////////////////////////////////
  24. #if !defined(RATL_COMMON_INC)
  25. #include "ratl_common.h"
  26. #endif
  27. namespace ratl
  28. {
  29. ////////////////////////////////////////////////////////////////////////////////////////
  30. // The Vector Class
  31. ////////////////////////////////////////////////////////////////////////////////////////
  32. template<class T>
  33. class heap_base : public ratl_base
  34. {
  35. public:
  36. typedef typename T TStorageTraits;
  37. typedef typename T::TValue TTValue;
  38. ////////////////////////////////////////////////////////////////////////////////////
  39. // Capacity Enum
  40. ////////////////////////////////////////////////////////////////////////////////////
  41. enum
  42. {
  43. CAPACITY = T::CAPACITY
  44. };
  45. ////////////////////////////////////////////////////////////////////////////////////
  46. // Data
  47. ////////////////////////////////////////////////////////////////////////////////////
  48. private:
  49. array_base<TStorageTraits> mData; // The Memory
  50. int mPush; // Address Of Next Add Location
  51. ////////////////////////////////////////////////////////////////////////////////////
  52. // Returns The Location Of Node (i)'s Parent Node (The Parent Node Of Zero Is Zero)
  53. ////////////////////////////////////////////////////////////////////////////////////
  54. static int parent(int i)
  55. {
  56. return ((i-1)/2);
  57. }
  58. ////////////////////////////////////////////////////////////////////////////////////
  59. // Returns The Location Of Node (i)'s Left Child (The Child Of A Leaf Is The Leaf)
  60. ////////////////////////////////////////////////////////////////////////////////////
  61. static int left(int i)
  62. {
  63. return (2*i)+1;
  64. }
  65. ////////////////////////////////////////////////////////////////////////////////////
  66. // Returns The Location Of Node (i)'s Right Child (The Child Of A Leaf Is The Leaf)
  67. ////////////////////////////////////////////////////////////////////////////////////
  68. static int right(int i)
  69. {
  70. return (2*i)+2;
  71. }
  72. ////////////////////////////////////////////////////////////////////////////////////
  73. // Returns The Location Of Largest Child Of Node (i)
  74. ////////////////////////////////////////////////////////////////////////////////////
  75. int largest_child(int i) const
  76. {
  77. if (left(i)<mPush)
  78. {
  79. if (right(i)<mPush)
  80. {
  81. return ( (mData[right(i)] < mData[left(i)]) ? (left(i)) : (right(i)) );
  82. }
  83. return left(i); // Node i only has a left child, so by default it is the biggest
  84. }
  85. return i; // Node i is a leaf, so just return it
  86. }
  87. ////////////////////////////////////////////////////////////////////////////////////
  88. // Swaps Two Element Locations
  89. ////////////////////////////////////////////////////////////////////////////////////
  90. void swap(int a, int b)
  91. {
  92. if (a==b)
  93. {
  94. return;
  95. }
  96. assert(a>=0 && b>=0 && a<CAPACITY && b<CAPACITY);
  97. mData.swap(a,b);
  98. }
  99. ////////////////////////////////////////////////////////////////////////////////////
  100. // Swaps The Data Up The Heap Until It Reaches A Valid Location
  101. ////////////////////////////////////////////////////////////////////////////////////
  102. void reheapify_upward(int Pos)
  103. {
  104. while (Pos && mData[parent(Pos)]<mData[Pos])
  105. {
  106. swap(parent(Pos), Pos);
  107. Pos = parent(Pos);
  108. }
  109. }
  110. ////////////////////////////////////////////////////////////////////////////////////
  111. // Swaps The Data Down The Heap Until It Reaches A Valid Location
  112. ////////////////////////////////////////////////////////////////////////////////////
  113. void reheapify_downward(int Pos)
  114. {
  115. int largestChild = largest_child(Pos);
  116. while (largestChild!=Pos && mData[Pos]<mData[largestChild])
  117. {
  118. swap(largestChild, Pos);
  119. Pos = largestChild;
  120. largestChild = largest_child(Pos);
  121. }
  122. }
  123. ////////////////////////////////////////////////////////////////////////////////////
  124. // Validate Will Run Through The Heap And Make Sure The Top Element Is Smallest
  125. ////////////////////////////////////////////////////////////////////////////////////
  126. bool valid()
  127. {
  128. for (int i=1; i<mPush; i++)
  129. {
  130. if (mData[0]<mData[i])
  131. {
  132. return false;
  133. }
  134. }
  135. return true;
  136. }
  137. public:
  138. ////////////////////////////////////////////////////////////////////////////////////
  139. // Constructor
  140. ////////////////////////////////////////////////////////////////////////////////////
  141. heap_base() : mPush(0)
  142. {
  143. }
  144. ////////////////////////////////////////////////////////////////////////////////////
  145. // Get The Size (The Difference Between The Push And Pop "Pointers")
  146. ////////////////////////////////////////////////////////////////////////////////////
  147. int size() const
  148. {
  149. return mPush;
  150. }
  151. ////////////////////////////////////////////////////////////////////////////////////
  152. // Check To See If The Size Is Zero
  153. ////////////////////////////////////////////////////////////////////////////////////
  154. bool empty() const
  155. {
  156. return !size();
  157. }
  158. ////////////////////////////////////////////////////////////////////////////////////
  159. // Check To See If The Size Is Full
  160. ////////////////////////////////////////////////////////////////////////////////////
  161. bool full() const
  162. {
  163. return size()==CAPACITY;
  164. }
  165. ////////////////////////////////////////////////////////////////////////////////////
  166. // Empty Out The Entire Heap
  167. ////////////////////////////////////////////////////////////////////////////////////
  168. void clear()
  169. {
  170. mPush = 0;
  171. mData.clear();
  172. }
  173. ////////////////////////////////////////////////////////////////////////////////////
  174. // Get The Data Value At The Top Of The Heap
  175. ////////////////////////////////////////////////////////////////////////////////////
  176. const TTValue & top() const
  177. {
  178. assert(mPush>0); // Don't Try To Look At This If There Is Nothing In Here
  179. return mData[0];
  180. }
  181. ////////////////////////////////////////////////////////////////////////////////////
  182. // Add A Value To The Queue
  183. ////////////////////////////////////////////////////////////////////////////////////
  184. void push(const TTValue& nValue)
  185. {
  186. assert(size()<CAPACITY);
  187. // Add It
  188. //--------
  189. mData.construct(mPush,nValue);
  190. // Fix Possible Heap Inconsistancies
  191. //-----------------------------------
  192. reheapify_upward(mPush);
  193. mPush++;
  194. assert(valid());
  195. }
  196. ////////////////////////////////////////////////////////////////////////////////////
  197. // Alloc A Value, call push_alloced to add
  198. ////////////////////////////////////////////////////////////////////////////////////
  199. TTValue& alloc()
  200. {
  201. assert(size()<CAPACITY);
  202. // Add It
  203. //--------
  204. mData.construct(mPush);
  205. return mData[mPush];
  206. }
  207. ////////////////////////////////////////////////////////////////////////////////////
  208. // Alloc A Raw Value for placement new, call push_alloced to add
  209. ////////////////////////////////////////////////////////////////////////////////////
  210. TRatlNew * alloc_raw()
  211. {
  212. assert(size()<CAPACITY);
  213. return mData.alloc_raw(mPush);
  214. }
  215. ////////////////////////////////////////////////////////////////////////////////////
  216. // Add A Value To The Queue, after filling an alloced slot
  217. ////////////////////////////////////////////////////////////////////////////////////
  218. void push_alloced()
  219. {
  220. assert(size()<CAPACITY);
  221. // Fix Possible Heap Inconsistancies
  222. //-----------------------------------
  223. reheapify_upward(mPush);
  224. mPush++;
  225. assert(valid());
  226. }
  227. ////////////////////////////////////////////////////////////////////////////////////
  228. // Remove A Value From The Queue
  229. ////////////////////////////////////////////////////////////////////////////////////
  230. void pop()
  231. {
  232. assert(size()>0);
  233. mPush--;
  234. // Swap The Lowest Element Up To The Spot We Just "Erased"
  235. //---------------------------------------------------------
  236. swap(0, mPush);
  237. mData.destruct(mPush);
  238. // Fix Possible Heap Inconsistancies
  239. //-----------------------------------
  240. reheapify_downward(0);
  241. assert(valid());
  242. }
  243. };
  244. template<class T, int ARG_CAPACITY>
  245. class heap_vs : public heap_base<storage::value_semantics<T,ARG_CAPACITY> >
  246. {
  247. public:
  248. typedef typename storage::value_semantics<T,ARG_CAPACITY> TStorageTraits;
  249. typedef typename TStorageTraits::TValue TTValue;
  250. enum
  251. {
  252. CAPACITY = ARG_CAPACITY
  253. };
  254. heap_vs() {}
  255. };
  256. template<class T, int ARG_CAPACITY>
  257. class heap_os : public heap_base<storage::object_semantics<T,ARG_CAPACITY> >
  258. {
  259. public:
  260. typedef typename storage::object_semantics<T,ARG_CAPACITY> TStorageTraits;
  261. typedef typename TStorageTraits::TValue TTValue;
  262. enum
  263. {
  264. CAPACITY = ARG_CAPACITY
  265. };
  266. heap_os() {}
  267. };
  268. template<class T, int ARG_CAPACITY, int ARG_MAX_CLASS_SIZE>
  269. class heap_is : public heap_base<storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> >
  270. {
  271. public:
  272. typedef typename storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> TStorageTraits;
  273. typedef typename TStorageTraits::TValue TTValue;
  274. enum
  275. {
  276. CAPACITY = ARG_CAPACITY,
  277. MAX_CLASS_SIZE = ARG_MAX_CLASS_SIZE
  278. };
  279. heap_is() {}
  280. };
  281. }
  282. #endif