UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
BinaryHeap.h
Go to the documentation of this file.
1// Copyright (C) 2009 Nine Realms, Inc
2//
3
4#pragma once
5
6#include "CoreTypes.h"
7#include "HAL/UnrealMemory.h"
9
10#include <type_traits>
11
12/*-----------------------------------------------------------------------------
13 Binary Heap, used to index another data structure.
14
15 Also known as a priority queue. Smallest key at top.
16 KeyType must implement operator<
17-----------------------------------------------------------------------------*/
18template< typename KeyType, typename IndexType = uint32 >
20{
21public:
22 static_assert(std::is_unsigned_v<IndexType>, "FBinaryHeap only supports unsigned index types");
23
27
28 FBinaryHeap(const FBinaryHeap&) = delete;
29 void operator =(const FBinaryHeap&) = delete;
31
32 void Clear();
33 void Free();
35
36 [[nodiscard]] bool IsEmpty() const { return HeapNum == 0; }
37 [[nodiscard]] uint32 Num() const { return HeapNum; }
38 [[nodiscard]] uint32 GetHeapSize() const { return HeapSize; }
39 [[nodiscard]] uint32 GetIndexSize() const { return IndexSize; }
40
41 [[nodiscard]] bool IsPresent( IndexType Index ) const;
42 [[nodiscard]] KeyType GetKey( IndexType Index ) const;
43 [[nodiscard]] IndexType Peek( IndexType Index ) const;
44
45 [[nodiscard]] IndexType Top() const;
46 void Pop();
47
48 void Add( KeyType Key, IndexType Index );
49 void Update( KeyType Key, IndexType Index );
50 void Remove( IndexType Index );
51
52protected:
55
56 void UpHeap( IndexType HeapIndex );
57 void DownHeap( IndexType HeapIndex );
58
63
67
68 IndexType* Heap;
69
70 KeyType* Keys;
71 IndexType* HeapIndexes;
72};
73
74template< typename KeyType, typename IndexType >
79
80template< typename KeyType, typename IndexType >
82 : HeapNum(0)
83 , HeapSize( InHeapSize )
84 , IndexSize( InIndexSize )
85{
86 Heap = new IndexType[ HeapSize ];
87 Keys = new KeyType[ IndexSize ];
88 HeapIndexes = new IndexType[ IndexSize ];
89
90 FMemory::Memset( HeapIndexes, 0xff, IndexSize * sizeof( IndexType ) );
91}
92
93template< typename KeyType, typename IndexType >
95{
96 HeapNum = Other.HeapNum;
97 HeapSize = Other.HeapSize;
98 IndexSize = Other.IndexSize;
99
100 Heap = Other.Heap;
101 Keys = Other.Keys;
102 HeapIndexes = Other.HeapIndexes;
103
104 Other.ResetInternal();
105}
106
107template< typename KeyType, typename IndexType >
112
113template< typename KeyType, typename IndexType >
115{
116 HeapNum = 0;
117 FMemory::Memset( HeapIndexes, 0xff, IndexSize * sizeof( IndexType ) );
118}
119
120template< typename KeyType, typename IndexType >
122{
123 delete[] Heap;
124 delete[] Keys;
125 delete[] HeapIndexes;
126
127 ResetInternal();
128}
129
130template< typename KeyType, typename IndexType >
132{
133 checkSlow( NewHeapSize != HeapSize );
134
135 if( NewHeapSize == 0 )
136 {
137 HeapNum = 0;
138 HeapSize = 0;
139
140 delete[] Heap;
141 Heap = nullptr;
142
143 return;
144 }
145
146 IndexType* NewHeap = new IndexType[ NewHeapSize ];
147
148 if( HeapSize != 0 )
149 {
150 FMemory::Memcpy( NewHeap, Heap, HeapSize * sizeof( IndexType ) );
151 delete[] Heap;
152 }
153
154 HeapNum = FMath::Min( HeapNum, NewHeapSize );
155 HeapSize = NewHeapSize;
156 Heap = NewHeap;
157}
158
159template< typename KeyType, typename IndexType >
161{
162 checkSlow( NewIndexSize != IndexSize );
163
164 if( NewIndexSize == 0 )
165 {
166 IndexSize = 0;
167
168 delete[] Keys;
169 delete[] HeapIndexes;
170
171 Keys = nullptr;
172 HeapIndexes = nullptr;
173
174 return;
175 }
176
177 KeyType* NewKeys = new KeyType[ NewIndexSize ];
178 IndexType* NewHeapIndexes = new IndexType[ NewIndexSize ];
179
180 if( IndexSize != 0 )
181 {
182 check( NewIndexSize >= IndexSize );
183
184 for( uint32 i = 0; i < IndexSize; i++ )
185 {
186 NewKeys[i] = Keys[i];
187 NewHeapIndexes[i] = HeapIndexes[i];
188 }
189 delete[] Keys;
190 delete[] HeapIndexes;
191 }
192
193 for( uint32 i = IndexSize; i < NewIndexSize; i++ )
194 {
195 NewHeapIndexes[i] = (IndexType)-1;
196 }
197
198 IndexSize = NewIndexSize;
199 Keys = NewKeys;
200 HeapIndexes = NewHeapIndexes;
201}
202
203template< typename KeyType, typename IndexType >
205{
206 if( NewHeapSize != HeapSize )
207 {
208 ResizeHeap( NewHeapSize );
209 }
210
211 if( NewIndexSize != IndexSize )
212 {
213 ResizeIndexes( NewIndexSize );
214 }
215}
216
217template< typename KeyType, typename IndexType >
219{
220 if (Index >= IndexSize)
221 {
222 return false;
223 }
224 return HeapIndexes[ Index ] != (IndexType)-1;
225}
226
227template< typename KeyType, typename IndexType >
228[[nodiscard]] inline KeyType FBinaryHeap< KeyType, IndexType >::GetKey( IndexType Index ) const
229{
230 checkSlow( IsPresent( Index ) );
231 return Keys[ Index ];
232}
233
234template< typename KeyType, typename IndexType >
235[[nodiscard]] inline IndexType FBinaryHeap< KeyType, IndexType >::Peek(IndexType Index) const
236{
237 checkSlow(Index < HeapNum);
238 return Heap[Index];
239}
240
241template< typename KeyType, typename IndexType >
243{
244 checkSlow( Heap );
245 checkSlow( HeapNum > 0 );
246 return Heap[0];
247}
248
249template< typename KeyType, typename IndexType >
251{
252 checkSlow( Heap );
253 checkSlow( HeapNum > 0 );
254
255 IndexType Index = Heap[0];
256
257 Heap[0] = Heap[ --HeapNum ];
258 HeapIndexes[ Heap[0] ] = 0;
259 HeapIndexes[ Index ] = (IndexType)-1;
260
261 DownHeap(0);
262}
263
264template< typename KeyType, typename IndexType >
265inline void FBinaryHeap< KeyType, IndexType >::Add( KeyType Key, IndexType Index )
266{
267 if( HeapNum == HeapSize )
268 {
269 ResizeHeap( FMath::Max<uint32>( 32u, HeapSize * 2 ) );
270 }
271
272 if( Index >= IndexSize )
273 {
274 ResizeIndexes(FMath::Max<uint32>(32u, FMath::RoundUpToPowerOfTwo(Index + 1)));
275 }
276
277 checkSlow( !IsPresent( Index ) );
278
279 IndexType HeapIndex = HeapNum++;
280 Heap[ HeapIndex ] = Index;
281
282 Keys[ Index ] = Key;
283 HeapIndexes[ Index ] = HeapIndex;
284
285 UpHeap( HeapIndex );
286}
287
288template< typename KeyType, typename IndexType >
289inline void FBinaryHeap< KeyType, IndexType >::Update( KeyType Key, IndexType Index )
290{
291 checkSlow( Heap );
292 checkSlow( IsPresent( Index ) );
293
294 Keys[ Index ] = Key;
295
296 IndexType HeapIndex = HeapIndexes[ Index ];
297 IndexType Parent = (HeapIndex - 1) >> 1;
298 if( HeapIndex > 0 && Key < Keys[ Heap[ Parent ] ] )
299 {
300 UpHeap( HeapIndex );
301 }
302 else
303 {
304 DownHeap( HeapIndex );
305 }
306}
307
308template< typename KeyType, typename IndexType >
310{
311 if( !IsPresent( Index ) )
312 {
313 return;
314 }
315
316 KeyType Key = Keys[ Index ];
317 IndexType HeapIndex = HeapIndexes[ Index ];
318
319 Heap[ HeapIndex ] = Heap[ --HeapNum ];
320 HeapIndexes[ Heap[ HeapIndex ] ] = HeapIndex;
321 HeapIndexes[ Index ] = (IndexType)-1;
322
323 if( Key < Keys[ Heap[ HeapIndex ] ] )
324 {
325 DownHeap( HeapIndex );
326 }
327 else
328 {
329 UpHeap( HeapIndex );
330 }
331}
332
333template< typename KeyType, typename IndexType >
335{
336 IndexType Moving = Heap[ HeapIndex ];
337 IndexType i = HeapIndex;
338 IndexType Parent = (i - 1) >> 1;
339
340 while( i > 0 && Keys[ Moving ] < Keys[ Heap[ Parent ] ] )
341 {
342 Heap[i] = Heap[ Parent ];
343 HeapIndexes[ Heap[i] ] = i;
344
345 i = Parent;
346 Parent = (i - 1) >> 1;
347 }
348
349 if( i != HeapIndex )
350 {
351 Heap[i] = Moving;
352 HeapIndexes[ Heap[i] ] = i;
353 }
354}
355
356template< typename KeyType, typename IndexType >
358{
359 IndexType Moving = Heap[ HeapIndex ];
360 IndexType i = HeapIndex;
361 IndexType Left = (i << 1) + 1;
362 IndexType Right = Left + 1;
363
364 while( Left < HeapNum )
365 {
366 IndexType Smallest = Left;
367 if( Right < HeapNum )
368 {
369 Smallest = ( Keys[ Heap[Left] ] < Keys[ Heap[Right] ] ) ? Left : Right;
370 }
371
372 if( Keys[ Heap[Smallest] ] < Keys[ Moving ] )
373 {
374 Heap[i] = Heap[ Smallest ];
375 HeapIndexes[ Heap[i] ] = i;
376
377 i = Smallest;
378 Left = (i << 1) + 1;
379 Right = Left + 1;
380 }
381 else
382 {
383 break;
384 }
385 }
386
387 if( i != HeapIndex )
388 {
389 Heap[i] = Moving;
390 HeapIndexes[ Heap[i] ] = i;
391 }
392}
393
394template< typename KeyType, typename IndexType >
396{
397 HeapNum = 0;
398 HeapSize = 0;
399 IndexSize = 0;
400 Heap = nullptr;
401 Keys = nullptr;
402 HeapIndexes = nullptr;
403}
404
405#if UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_5_4
406#include "Templates/IsSigned.h"
407#endif
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define check(expr)
Definition AssertionMacros.h:314
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition BinaryHeap.h:20
FBinaryHeap(const FBinaryHeap &)=delete
uint32 GetIndexSize() const
Definition BinaryHeap.h:39
void Resize(uint32 NewHeapSize, uint32 NewIndexSize)
Definition BinaryHeap.h:204
FBinaryHeap()
Definition BinaryHeap.h:75
bool IsEmpty() const
Definition BinaryHeap.h:36
void operator=(const FBinaryHeap &)=delete
FBinaryHeap(FBinaryHeap &&Other)
Definition BinaryHeap.h:94
IndexType * Heap
Definition BinaryHeap.h:68
bool IsPresent(IndexType Index) const
Definition BinaryHeap.h:218
KeyType GetKey(IndexType Index) const
Definition BinaryHeap.h:228
void ResizeHeap(uint32 NewHeapSize)
Definition BinaryHeap.h:131
KeyType * Keys
Definition BinaryHeap.h:70
IndexType Peek(IndexType Index) const
Definition BinaryHeap.h:235
void DownHeap(IndexType HeapIndex)
Definition BinaryHeap.h:357
FBinaryHeap(uint32 InHeapSize, uint32 InIndexSize)
Definition BinaryHeap.h:81
void UpHeap(IndexType HeapIndex)
Definition BinaryHeap.h:334
void Update(KeyType Key, IndexType Index)
Definition BinaryHeap.h:289
uint32 IndexSize
Definition BinaryHeap.h:66
void ResetInternal()
Definition BinaryHeap.h:395
void Add(KeyType Key, IndexType Index)
Definition BinaryHeap.h:265
IndexType Top() const
Definition BinaryHeap.h:242
void ResizeIndexes(uint32 NewIndexSize)
Definition BinaryHeap.h:160
void Free()
Definition BinaryHeap.h:121
uint32 Num() const
Definition BinaryHeap.h:37
void Remove(IndexType Index)
Definition BinaryHeap.h:309
IndexType * HeapIndexes
Definition BinaryHeap.h:71
uint32 HeapSize
Definition BinaryHeap.h:65
~FBinaryHeap()
Definition BinaryHeap.h:108
void Pop()
Definition BinaryHeap.h:250
uint32 GetHeapSize() const
Definition BinaryHeap.h:38
uint32 HeapNum
Definition BinaryHeap.h:64
void Clear()
Definition BinaryHeap.h:114
U16 Index
Definition radfft.cpp:71
static UE_FORCEINLINE_HINT void * Memcpy(void *Dest, const void *Src, SIZE_T Count)
Definition UnrealMemory.h:160
static UE_FORCEINLINE_HINT void * Memset(void *Dest, uint8 Char, SIZE_T Count)
Definition UnrealMemory.h:119