gwnavruntime/containers/binaryheap.h Source File

binaryheap.h
Go to the documentation of this file.
1 /*
2 * Copyright 2015 Autodesk, Inc. All rights reserved.
3 * Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
4 * or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
5 */
6 
7 
8 #ifndef Navigation_BinaryHeap_H
9 #define Navigation_BinaryHeap_H
10 
16 
17 namespace Kaim
18 {
19 
20 static const KyUInt32 BinaryHeapInvalidReference = KyUInt32MAXVAL;
21 
22 /* Class for BinaryHeap to ignore index tracking. */
23 template <typename T>
24 class BinaryHeapIndexTracker_None
25 {
26 public:
27  static void OnAdd(T& /*value*/, KyUInt32 /*indexInBinaryHeap*/) {}
28  static void OnRemove(T& /*value*/) {}
29  static void OnSwap(T& /*lhs*/, T& /*rhs*/) {}
30 };
31 
32 /* Class for BinaryHeap to update index in binaryHeap assuming index is T::m_indexInBinaryHeap. */
33 template <typename T>
34 class BinaryHeapIndexTracker_IndexInBinaryHeap
35 {
36 public:
37  // Called after the element has been added.
38  static KY_INLINE void OnAdd(T& value, KyUInt32 indexInBinaryHeap) { value.m_indexInBinaryHeap = indexInBinaryHeap; }
39  // Called before the element has been removed.
40  static KY_INLINE void OnRemove(T& value) { value.m_indexInBinaryHeap = BinaryHeapInvalidReference; }
41  // Called after the elements has been swapped.
42  static KY_INLINE void OnSwap(T& lhs, T& rhs) { Alg::Swap(lhs.m_indexInBinaryHeap, rhs.m_indexInBinaryHeap); }
43 };
44 
45 /* Class for BinaryHeap to update index in binaryHeap assuming index is T::m_indexInBinaryHeap.
46  Specialisation for pointer.
47 */
48 template <typename T>
49 class BinaryHeapIndexTracker_IndexInBinaryHeap<T*>
50 {
51 public:
52  // Called after the element has been added.
53  static KY_INLINE void OnAdd(T*& value, KyUInt32 indexInBinaryHeap) { value->m_indexInBinaryHeap = indexInBinaryHeap; }
54  // Called before the element has been removed.
55  static KY_INLINE void OnRemove(T*& value) { value->m_indexInBinaryHeap = BinaryHeapInvalidReference; }
56  // Called after the elements has been swapped.
57  static KY_INLINE void OnSwap(T*& lhs, T*& rhs) { Alg::Swap(lhs->m_indexInBinaryHeap, rhs->m_indexInBinaryHeap); }
58 };
59 
60 /*
61  BinaryHeap is a class in which the first element is always the element with the "best" cost (according to Comparator)
62  BinaryHeapIndexTracker is a class which is used to keep a track of index in BinaryHeap to allow removal or update or internal element.
63  (@see BinaryHeapIndexTracker_IndexInBinaryHeap as example of BinaryHeapIndexTracker).
64 */
65 template <class T, typename ArrayType = KyArray<T>, typename Comparator = DefaultLess<T>, typename BinaryHeapIndexTracker = BinaryHeapIndexTracker_None<T> >
66 class BinaryHeap
67 {
68  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
69 public:
70 
71  typedef typename ArrayType::Iterator Iterator;
72  typedef typename ArrayType::ConstIterator ConstIterator;
73 
74 public:
75  /* Retrieves the first sorted element in the container.
76  \pre IsEmpty() == false */
77  KY_INLINE void GetFirst(T& item) const;
78 
79  /* Retrieves the first sorted element in the container.
80  \pre IsEmpty() == false */
81  KY_INLINE const T& GetFirst() const { return *Begin(); }
82 
83  /* Add a element in the container.
84  \post IsSorted() == true */
85  void Insert(const T& item);
86 
87  /* Removes the first sorted element in the container.
88  \pre IsEmpty() == false
89  \post IsSorted() == true */
90  void ExtractFirst();
91 
92  /* Removes and retrieves the first sorted element in the container.
93  \pre IsEmpty() == false
94  \post IsSorted() == true */
95  void ExtractFirst(T& item);
96 
97  KY_INLINE void Clear() { m_heap.Clear(); }
98  KY_INLINE void Reserve(KyUInt32 size) { return m_heap.Reserve(size); }
99 
100  KY_INLINE KyUInt32 GetCount() const { return (KyUInt32)m_heap.GetSize();}
101  KY_INLINE KyUInt32 GetCapacity() const { return (KyUInt32)m_heap.GetCapacity();}
102  KY_INLINE bool IsEmpty() const { return GetCount() == 0; }
103 
104  bool IsSorted() const;
105 
106  /* Retrieves the referenced element in the container.
107  \pre index < GetCount() */
108  void At(KyUInt32 index, T& item);
109 
110  KY_INLINE const T& operator[](KyUInt32 index) const { return m_heap[index]; }
111  KY_INLINE T& operator[](KyUInt32 index) { return m_heap[index]; }
112 
113  /* Updates the referenced element and sort the container.
114  \pre index < GetCount()
115  \post IsSorted() == true */
116  void UpdateAt(KyUInt32 index);
117 
118  /* Removes the referenced element in the container.
119  \pre index < GetCount()
120  \post IsSorted() == true */
121  void RemoveAt(KyUInt32 index);
122 
123  /* Removes the element pointed by the iterator in the container.
124  \post IsSorted() == true
125  \returns An iterator pointing to the following element in the container.*/
126  Iterator Erase(Iterator it);
127 
128  /* Returns an iterator that points to the first element in the container. */
129  KY_INLINE ConstIterator Begin() const { return m_heap.Begin(); }
130  KY_INLINE Iterator Begin() { return m_heap.Begin(); }
131 
132  /* Returns an iterator that points after the last element in the container. */
133  KY_INLINE ConstIterator End() const { return m_heap.End(); }
134  KY_INLINE Iterator End() { return m_heap.End(); }
135 
136  Comparator& GetComparator() { return m_comparator; }
137  ArrayType& GetHeap() { return m_heap; }
138 private:
139  KY_INLINE ConstIterator GetLast() const { return ConstIterator(&m_heap, (GetCount() - 1)); }
140  KY_INLINE Iterator GetLast() { return Iterator(&m_heap, (GetCount() - 1)); }
141 
142  KY_INLINE ConstIterator GetParent(ConstIterator it) const {return Begin() + ((GetIndex(it) - 1) >> 1);}
143  KY_INLINE Iterator GetParent(Iterator it) {return Begin() + ((GetIndex(it) - 1) >> 1);}
144 
145  /* Returns an iterator that points to the left child element in the container */
146  KY_INLINE ConstIterator GetLeft(ConstIterator it) const {return Begin() + 1 + (GetIndex(it) << 1);}
147  KY_INLINE Iterator GetLeft(Iterator it) {return Begin() + 1 + (GetIndex(it) << 1);}
148 
149  /* Returns an iterator that points to the right child element in the container */
150  KY_INLINE ConstIterator GetRight(ConstIterator it) const {return Begin() + 2 + (GetIndex(it) << 1);}
151  KY_INLINE Iterator GetRight(Iterator it) {return Begin() + 2 + (GetIndex(it) << 1);}
152 
153  KY_INLINE KyUInt32 GetIndex(ConstIterator it) const { return KyUInt32(it.GetIndex()); }
154  KY_INLINE KyUInt32 GetIndex(Iterator it) const { return KyUInt32(it.GetIndex()); }
155 
156  /* Moves an element towards the first element until it is sorted.*/
157  void PercolateUp(Iterator hole);
158 
159  /* Moves an element towards the last element until it is sorted.*/
160  void PercolateDown(Iterator hole);
161 
162 private:
163  ArrayType m_heap;
164  Comparator m_comparator;
165 };
166 
167 } // namespace Kaim
168 
170 
171 #endif // Navigation_BinaryHeap_H
Definition: gamekitcrowddispersion.h:20
#define KY_DEFINE_NEW_DELETE_OPERATORS(MemStat)
This macro defines new and delete operators.
Definition: memory.h:137
unsigned int KyUInt32
Type used internally to represent an unsigned 32-bit integer.
Definition: types.h:36
#define KyUInt32MAXVAL
The maximum value that can be stored in the KyUInt32 variable type.
Definition: types.h:226