source: GTP/trunk/Lib/Vis/Preprocessing/src/FlexibleHeap.h @ 2360

Revision 2360, 4.8 KB checked in by mattausch, 18 years ago (diff)
Line 
1#ifndef FLEXIBLEHEAP_H
2#define FLEXIBLEHEAP_H
3
4#include <vector>
5
6
7namespace GtpVisibilityPreprocessor {
8
9const static int NOT_IN_HEAP = -100;
10
11/** This class implements an element for a heap.
12        Classes using the heap should be inherited from this class.
13*/
14class Heapable
15{
16public:
17       
18        Heapable(): mPriority(0) { NotInHeap(); SetPriority(0.0f); }
19
20        inline bool IsInHeap() { return mPosition != NOT_IN_HEAP; }
21        inline void NotInHeap() { mPosition = NOT_IN_HEAP; }
22        inline int GetHeapPos() { return mPosition; }
23        inline void SetHeapPos(const int t) { mPosition = t; }
24
25        inline void  SetPriority(const float k) { mPriority = k; }
26        //inline float GetPriority() const  { return mPriority; }
27        virtual float GetPriority() const = 0;
28
29protected:
30
31        float mPriority;
32        int mPosition;
33};
34
35
36/** This class implements a flexible heap for
37use as a priority queue.
38
39Unlike the stl priority_queue, the class allows access to all
40elements. It implements efficient insertion routines and remove routines
41of arbitrary elements.
42*/
43template<typename T>
44class FlexibleHeap
45{
46public:
47        FlexibleHeap() { }
48        FlexibleHeap(const unsigned int n): mBuffer(n) { }
49
50        void Push(T t) { Push(t, t->GetPriority()); }
51        void Push(T t, const float priority);
52        bool Update(T t) { return Update(t, t->GetPriority()); }
53        bool Update(T t, const float priority);
54
55        unsigned int Size() const { return (unsigned int)mBuffer.size(); }
56        bool Empty() const {return mBuffer.empty(); }
57        T Item(const unsigned int i) { return mBuffer[i]; }
58        const T Item(const unsigned int i) const { return mBuffer[i]; }
59        T Pop();
60        T Top() const { return (mBuffer.empty() ? (T)NULL : mBuffer.front()); }
61        /** Erases the element from the heap.
62        */
63        T Erase(T);
64
65protected:
66
67        void Place(T x, const unsigned int i);
68        void Swap(const unsigned int i, const unsigned int j);
69
70        unsigned int Parent(const unsigned int i) const { return (i - 1) / 2; }
71        unsigned int Left(const unsigned int i) const { return 2 * i + 1; }
72        unsigned int Right(const unsigned int i) const { return 2 * i + 2; }
73
74        void UpHeap(const unsigned int i);
75        void DownHeap(const unsigned int i);
76
77        std::vector<T> mBuffer;
78};
79
80
81/*****************************************************************************/
82/*                         MyHeap implementation                             *
83/*****************************************************************************/
84
85template <typename T>
86inline void FlexibleHeap<T>::Place(T x, const unsigned int i)
87{
88        mBuffer[i] = x;
89        x->SetHeapPos(i);
90}
91
92
93template <typename T>
94void FlexibleHeap<T>::Swap(const unsigned int i, const unsigned int j)
95{
96        T tmp = mBuffer[i];
97
98        Place(mBuffer[j], i);
99        Place(tmp, j);
100}
101
102
103template <typename T>
104void FlexibleHeap<T>::UpHeap(const unsigned int i)
105{
106        T moving = mBuffer[i];
107        unsigned int index = i;
108        unsigned int p = Parent(i);
109
110        while ((index > 0) && (moving->GetPriority() > mBuffer[p]->GetPriority()))
111        {
112                Place(mBuffer[p], index);
113                index = p;
114                p = Parent(p);
115        }
116
117        if (index != i)
118        {
119                Place(moving, index);
120        }
121}
122
123template <typename T>
124void FlexibleHeap<T>::DownHeap(const unsigned int i)
125{
126        T moving = mBuffer[i];
127
128        unsigned int index = i;
129        unsigned int l = Left(i);
130        unsigned int r = Right(i);
131        unsigned int largest;
132
133        while (l < (int)mBuffer.size())
134        {
135                if ((r < (unsigned int)mBuffer.size()) && (mBuffer[l]->GetPriority() < mBuffer[r]->GetPriority()))
136                        largest = r;
137                else
138                        largest = l;
139
140                if (moving->GetPriority() < mBuffer[largest]->GetPriority())
141                {
142                        Place(mBuffer[largest], index);
143                        index = largest;
144                        l = Left(index);
145                        r = Right(index);
146                }
147                else
148                {
149                        break;
150                }
151        }
152
153        if (index != i)
154        {
155                Place(moving, index);
156        }
157}
158
159
160template <typename T>
161void FlexibleHeap<T>::Push(T t, const float v)
162{
163        t->SetPriority(v);
164
165        unsigned int i = (unsigned int)mBuffer.size();
166
167        t->SetHeapPos(i);
168        mBuffer.push_back(t);
169
170        UpHeap(i);
171}
172
173template <typename T>
174bool FlexibleHeap<T>::Update(T t, const float v)
175{
176        if (t->IsInHeap())
177                return false;
178
179        t->SetPriority(v);
180
181        const unsigned int i = t->GetHeapPos();
182
183        if ((i > 0) && (v > mBuffer[Parent(i)]->GetPriority()))
184                UpHeap(i);
185        else
186                DownHeap(i);
187
188        return true;
189}
190
191template <typename T>
192T FlexibleHeap<T>::Pop()
193{
194        if (mBuffer.empty())
195                return NULL;
196
197        Swap(0, (int)mBuffer.size() - 1);
198
199        T dead = mBuffer.back();
200        mBuffer.pop_back();
201
202        DownHeap(0);
203        dead->NotInHeap();
204
205        return dead;
206}
207
208
209template <typename T>
210T FlexibleHeap<T>::Erase(T t)
211{
212        if (!t->IsInHeap())
213                return (T)NULL;
214
215        const int i = t->GetHeapPos();
216
217        Swap(i, (int)mBuffer.size() - 1);
218       
219        mBuffer.pop_back();
220        t->NotInHeap();
221
222        if (mBuffer[i]->GetPriority() < t->GetPriority())
223                DownHeap(i);
224        else
225                UpHeap(i);
226
227        return t;
228}
229
230}
231
232// FLEXIBLEHEAP_H
233#endif
Note: See TracBrowser for help on using the repository browser.