232 lines
4.0 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|