1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-23 18:18:00 +02:00
Beef/BeefLibs/corlib/src/Collections/Generic/BinaryHeap.bf

119 lines
2.4 KiB
Beef
Raw Normal View History

2019-08-23 11:56:54 -07:00
// This file contains portions of code released by Microsoft under the MIT license as part
// of an open-sourcing initiative in 2014 of the C# core libraries.
// The original source was submitted to https://github.com/Microsoft/referencesource
using System.Diagnostics;
namespace System.Collections.Generic
{
public class BinaryHeap<T>
{
protected T[] mData ~ delete _;
protected int32 mSize = 0;
protected Comparison<T> mComparison ~ delete _;
public this(Comparison<T> comparison)
{
Constructor(4, comparison);
}
public this(int32 capacity, Comparison<T> comparison)
{
Constructor(capacity, comparison);
}
private void Constructor(int32 capacity, Comparison<T> comparison)
{
mData = new T[capacity];
mComparison = comparison;
}
public int32 Size
{
get
{
return mSize;
}
}
/// Add an item to the heap
public void Add(T item)
{
if (mSize == mData.Count)
Resize();
mData[mSize] = item;
HeapifyUp(mSize);
mSize++;
}
/// Get the item of the root
public T Peek()
{
return mData[0];
}
/// Extract the item of the root
public T Pop()
{
T item = mData[0];
mSize--;
mData[0] = mData[mSize];
HeapifyDown(0);
return item;
}
public void Clear()
{
mSize = 0;
}
private void Resize()
{
T[] resizedData = new T[mData.Count * 2];
Array.Copy(mData, 0, resizedData, 0, mData.Count);
delete mData;
mData = resizedData;
}
[Optimize]
private void HeapifyUp(int32 childIdx)
{
if (childIdx > 0)
{
int32 parentIdx = (childIdx - 1) / 2;
if (mComparison(mData[childIdx], mData[parentIdx]) > 0)
{
// swap parent and child
T t = mData[parentIdx];
mData[parentIdx] = mData[childIdx];
mData[childIdx] = t;
HeapifyUp(parentIdx);
}
}
}
[Optimize]
private void HeapifyDown(int32 parentIdx)
{
int32 leftChildIdx = 2 * parentIdx + 1;
int32 rightChildIdx = leftChildIdx + 1;
int32 largestChildIdx = parentIdx;
if (leftChildIdx < mSize && mComparison(mData[leftChildIdx], mData[largestChildIdx]) > 0)
{
largestChildIdx = leftChildIdx;
}
if (rightChildIdx < mSize && mComparison(mData[rightChildIdx], mData[largestChildIdx]) > 0)
{
largestChildIdx = rightChildIdx;
}
if (largestChildIdx != parentIdx)
{
T t = mData[parentIdx];
mData[parentIdx] = mData[largestChildIdx];
mData[largestChildIdx] = t;
HeapifyDown(largestChildIdx);
}
}
}
}