Files
HX_MapEditor/Assets/Scripts/PathFinding/PriorityQueueB.cs
2025-06-14 13:46:24 +08:00

232 lines
4.0 KiB
C#

using System;
using System.Collections.Generic;
namespace HxGame.PathFinding
{
public interface IPriorityQueue<T>
{
int Push(T item);
T Pop();
T Peek();
void Update(int i);
}
public class PriorityQueueB<T> : IPriorityQueue<T>
{
protected T[] InnerList;
protected IComparer<T> mComparer;
protected int InnerListCount;
public PriorityQueueB()
{
mComparer = Comparer<T>.Default;
InnerList = new T[4096];
InnerListCount = 0;
}
public PriorityQueueB(IComparer<T> comparer)
{
mComparer = comparer;
InnerList = new T[4096];
InnerListCount = 0;
}
public IComparer<T> comparer { get { return mComparer; } }
protected void SwapElements(int i, int j)
{
T h = InnerList[i];
InnerList[i] = InnerList[j];
InnerList[j] = h;
}
protected virtual int OnCompare(int i, int j)
{
return mComparer.Compare(InnerList[i], InnerList[j]);
}
// <returns>列表中对象所在的索引</returns>
public int Push(T item)
{
int p = InnerListCount, p2;
if (InnerListCount >= InnerList.Length)
{
ResizeInnerList();
}
InnerList[InnerListCount++] = item;
do
{
if (p == 0)
break;
p2 = (p - 1) / 2;
T InnerListp = InnerList[p];
T InnerListp2 = InnerList[p2];
if (mComparer.Compare(InnerListp, InnerListp2) < 0)
{
// Swap
InnerList[p] = InnerListp2;
InnerList[p2] = InnerListp;
p = p2;
}
else
break;
} while (true);
return p;
}
void ResizeInnerList()
{
T[] newInnerList = new T[InnerListCount * 2];
Array.Copy(InnerList, newInnerList, InnerListCount);
InnerList = newInnerList;
}
/// <summary>
/// 获取最小的对象
/// </summary>
/// <returns></returns>
public T Pop()
{
T result = InnerList[0];
int p = 0, p1, p2, pn;
int count = InnerListCount - 1;
InnerList[0] = InnerList[count]; // InnerList.Count - 1
InnerListCount--;
do
{
pn = p;
p1 = 2 * p + 1;
p2 = p1 + 1; //2 * p + 2;
if (count > p1)
{
if (mComparer.Compare(InnerList[p], InnerList[p1]) > 0)
{
p = p1;
}
}
if (count > p2)
{
if (mComparer.Compare(InnerList[p], InnerList[p2]) > 0)
{
p = p2;
}
}
if (p == pn)
break;
// Swap
T h = InnerList[p];
InnerList[p] = InnerList[pn];
InnerList[pn] = h;
} while (true);
return result;
}
/// <summary>
/// 通知队列位置i处的对象已更改
/// 队列需要恢复秩序
/// 因为您无权访问任何索引(除非使用显式IList.this)
/// 您不应该在不确切知道自己在做什么的情况下调用此函数。
/// </summary>
/// <param name="i">更改对象的索引</param>
public void Update(int i)
{
int p = i, pn;
int p1, p2;
do
{ // aufsteigen
if (p == 0)
break;
p2 = (p - 1) / 2;
if (OnCompare(p, p2) < 0)
{
SwapElements(p, p2);
p = p2;
}
else
break;
} while (true);
if (p < i)
return;
do
{ // absteigen
pn = p;
p1 = 2 * p + 1;
p2 = 2 * p + 2;
if (InnerListCount > p1 && OnCompare(p, p1) > 0) // links kleiner
p = p1;
if (InnerListCount > p2 && OnCompare(p, p2) > 0) // rechts noch kleiner
p = p2;
if (p == pn)
break;
SwapElements(p, pn);
} while (true);
}
/// <summary>
/// 在不移除的情况下获取最小的对象
/// </summary>
/// <returns>最小的对象</returns>
public T Peek()
{
if (InnerListCount > 0)
return InnerList[0];
return default(T);
}
public void Clear()
{
InnerListCount = 0; //.Clear ();
}
public int Count
{
get { return InnerListCount; }
}
public void RemoveLocation(T item)
{
int index = -1;
for (int i = 0; i < InnerListCount; i++)
{
if (mComparer.Compare(InnerList[i], item) == 0)
{
index = i;
break;
}
}
if (index != -1)
{
//InnerList.RemoveAt (index);
for (int i = index; i < InnerListCount - 1; i++)
{
InnerList[i] = InnerList[i + 1];
}
InnerListCount--;
}
}
public T this[int index]
{
get { return InnerList[index]; }
set
{
InnerList[index] = value;
Update(index);
}
}
}
}