mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-08-05 18:24:12 +00:00
Public release of the DLU server code!
Have fun!
This commit is contained in:
251
thirdparty/raknet/Source/DS_Heap.h
vendored
Normal file
251
thirdparty/raknet/Source/DS_Heap.h
vendored
Normal file
@@ -0,0 +1,251 @@
|
||||
/// \file
|
||||
/// \brief \b [Internal] Heap (Also serves as a priority queue)
|
||||
///
|
||||
/// This file is part of RakNet Copyright 2003 Kevin Jenkins.
|
||||
///
|
||||
/// Usage of RakNet is subject to the appropriate license agreement.
|
||||
/// Creative Commons Licensees are subject to the
|
||||
/// license found at
|
||||
/// http://creativecommons.org/licenses/by-nc/2.5/
|
||||
/// Single application licensees are subject to the license found at
|
||||
/// http://www.jenkinssoftware.com/SingleApplicationLicense.html
|
||||
/// Custom license users are subject to the terms therein.
|
||||
/// GPL license users are subject to the GNU General Public
|
||||
/// License as published by the Free
|
||||
/// Software Foundation; either version 2 of the License, or (at your
|
||||
/// option) any later version.
|
||||
|
||||
#ifndef __RAKNET_HEAP_H
|
||||
#define __RAKNET_HEAP_H
|
||||
|
||||
#include "RakMemoryOverride.h"
|
||||
#include "DS_List.h"
|
||||
#include "Export.h"
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( push )
|
||||
#endif
|
||||
|
||||
/// The namespace DataStructures was only added to avoid compiler errors for commonly named data structures
|
||||
/// As these data structures are stand-alone, you can use them outside of RakNet for your own projects if you wish.
|
||||
namespace DataStructures
|
||||
{
|
||||
template <class weight_type, class data_type, bool isMaxHeap>
|
||||
class RAK_DLL_EXPORT Heap : public RakNet::RakMemoryOverride
|
||||
{
|
||||
public:
|
||||
struct HeapNode
|
||||
{
|
||||
HeapNode() {}
|
||||
HeapNode(const weight_type &w, const data_type &d) : weight(w), data(d) {}
|
||||
weight_type weight; // I'm assuming key is a native numerical type - float or int
|
||||
data_type data;
|
||||
};
|
||||
|
||||
Heap();
|
||||
~Heap();
|
||||
void Push(const weight_type &weight, const data_type &data);
|
||||
data_type Pop(const unsigned startingIndex);
|
||||
data_type Peek(const unsigned startingIndex=0) const;
|
||||
weight_type PeekWeight(const unsigned startingIndex=0) const;
|
||||
void Clear(void);
|
||||
data_type& operator[] ( const unsigned int position ) const;
|
||||
unsigned Size(void) const;
|
||||
|
||||
protected:
|
||||
unsigned LeftChild(const unsigned i) const;
|
||||
unsigned RightChild(const unsigned i) const;
|
||||
unsigned Parent(const unsigned i) const;
|
||||
void Swap(const unsigned i, const unsigned j);
|
||||
DataStructures::List<HeapNode> heap;
|
||||
};
|
||||
|
||||
template <class weight_type, class data_type, bool isMaxHeap>
|
||||
Heap<weight_type, data_type, isMaxHeap>::Heap()
|
||||
{
|
||||
}
|
||||
|
||||
template <class weight_type, class data_type, bool isMaxHeap>
|
||||
Heap<weight_type, data_type, isMaxHeap>::~Heap()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
template <class weight_type, class data_type, bool isMaxHeap>
|
||||
void Heap<weight_type, data_type, isMaxHeap>::Push(const weight_type &weight, const data_type &data)
|
||||
{
|
||||
unsigned currentIndex = heap.Size();
|
||||
unsigned parentIndex;
|
||||
heap.Insert(HeapNode(weight, data));
|
||||
while (currentIndex!=0)
|
||||
{
|
||||
parentIndex = Parent(currentIndex);
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( disable : 4127 ) // warning C4127: conditional expression is constant
|
||||
#endif
|
||||
if (isMaxHeap)
|
||||
{
|
||||
if (heap[parentIndex].weight < weight)
|
||||
{
|
||||
Swap(currentIndex, parentIndex);
|
||||
currentIndex=parentIndex;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (heap[parentIndex].weight > weight)
|
||||
{
|
||||
Swap(currentIndex, parentIndex);
|
||||
currentIndex=parentIndex;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class weight_type, class data_type, bool isMaxHeap>
|
||||
data_type Heap<weight_type, data_type, isMaxHeap>::Pop(const unsigned startingIndex)
|
||||
{
|
||||
// While we have children, swap out with the larger of the two children.
|
||||
|
||||
// This line will assert on an empty heap
|
||||
data_type returnValue=heap[0].data;
|
||||
|
||||
// Move the last element to the head, and re-heapify
|
||||
heap[startingIndex]=heap[heap.Size()-1];
|
||||
|
||||
unsigned currentIndex,leftChild,rightChild;
|
||||
weight_type currentWeight;
|
||||
currentIndex=startingIndex;
|
||||
currentWeight=heap[startingIndex].weight;
|
||||
heap.RemoveFromEnd();
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( disable : 4127 ) // warning C4127: conditional expression is constant
|
||||
#endif
|
||||
while (1)
|
||||
{
|
||||
leftChild=LeftChild(currentIndex);
|
||||
rightChild=RightChild(currentIndex);
|
||||
if (leftChild >= heap.Size())
|
||||
{
|
||||
// Done
|
||||
return returnValue;
|
||||
}
|
||||
if (rightChild >= heap.Size())
|
||||
{
|
||||
// Only left node.
|
||||
if ((isMaxHeap==true && currentWeight < heap[leftChild].weight) ||
|
||||
(isMaxHeap==false && currentWeight > heap[leftChild].weight))
|
||||
Swap(leftChild, currentIndex);
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Swap with the bigger/smaller of the two children and continue
|
||||
if (isMaxHeap)
|
||||
{
|
||||
if (heap[leftChild].weight <= currentWeight && heap[rightChild].weight <= currentWeight)
|
||||
return returnValue;
|
||||
|
||||
if (heap[leftChild].weight > heap[rightChild].weight)
|
||||
{
|
||||
Swap(leftChild, currentIndex);
|
||||
currentIndex=leftChild;
|
||||
}
|
||||
else
|
||||
{
|
||||
Swap(rightChild, currentIndex);
|
||||
currentIndex=rightChild;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (heap[leftChild].weight >= currentWeight && heap[rightChild].weight >= currentWeight)
|
||||
return returnValue;
|
||||
|
||||
if (heap[leftChild].weight < heap[rightChild].weight)
|
||||
{
|
||||
Swap(leftChild, currentIndex);
|
||||
currentIndex=leftChild;
|
||||
}
|
||||
else
|
||||
{
|
||||
Swap(rightChild, currentIndex);
|
||||
currentIndex=rightChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class weight_type, class data_type, bool isMaxHeap>
|
||||
data_type Heap<weight_type, data_type, isMaxHeap>::Peek(const unsigned startingIndex) const
|
||||
{
|
||||
return heap[startingIndex].data;
|
||||
}
|
||||
|
||||
template <class weight_type, class data_type, bool isMaxHeap>
|
||||
weight_type Heap<weight_type, data_type, isMaxHeap>::PeekWeight(const unsigned startingIndex) const
|
||||
{
|
||||
return heap[startingIndex].weight;
|
||||
}
|
||||
|
||||
template <class weight_type, class data_type, bool isMaxHeap>
|
||||
void Heap<weight_type, data_type, isMaxHeap>::Clear(void)
|
||||
{
|
||||
heap.Clear();
|
||||
}
|
||||
|
||||
template <class weight_type, class data_type, bool isMaxHeap>
|
||||
data_type& Heap<weight_type, data_type, isMaxHeap>::operator[] ( const unsigned int position ) const
|
||||
{
|
||||
return heap[position].data;
|
||||
}
|
||||
template <class weight_type, class data_type, bool isMaxHeap>
|
||||
unsigned Heap<weight_type, data_type, isMaxHeap>::Size(void) const
|
||||
{
|
||||
return heap.Size();
|
||||
}
|
||||
|
||||
template <class weight_type, class data_type, bool isMaxHeap>
|
||||
unsigned Heap<weight_type, data_type, isMaxHeap>::LeftChild(const unsigned i) const
|
||||
{
|
||||
return i*2+1;
|
||||
}
|
||||
|
||||
template <class weight_type, class data_type, bool isMaxHeap>
|
||||
unsigned Heap<weight_type, data_type, isMaxHeap>::RightChild(const unsigned i) const
|
||||
{
|
||||
return i*2+2;
|
||||
}
|
||||
|
||||
template <class weight_type, class data_type, bool isMaxHeap>
|
||||
unsigned Heap<weight_type, data_type, isMaxHeap>::Parent(const unsigned i) const
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
assert(i!=0);
|
||||
#endif
|
||||
return (i-1)/2;
|
||||
}
|
||||
|
||||
template <class weight_type, class data_type, bool isMaxHeap>
|
||||
void Heap<weight_type, data_type, isMaxHeap>::Swap(const unsigned i, const unsigned j)
|
||||
{
|
||||
HeapNode temp;
|
||||
temp=heap[i];
|
||||
heap[i]=heap[j];
|
||||
heap[j]=temp;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( pop )
|
||||
#endif
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user