using System; using System.Collections.Generic; namespace HxGame.PathFinding { public interface IPriorityQueue { int Push(T item); T Pop(); T Peek(); void Update(int i); } public class PriorityQueueB : IPriorityQueue { protected T[] InnerList; protected IComparer mComparer; protected int InnerListCount; public PriorityQueueB() { mComparer = Comparer.Default; InnerList = new T[4096]; InnerListCount = 0; } public PriorityQueueB(IComparer comparer) { mComparer = comparer; InnerList = new T[4096]; InnerListCount = 0; } public IComparer 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]); } // 列表中对象所在的索引 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; } /// /// 获取最小的对象 /// /// 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; } /// /// 通知队列位置i处的对象已更改 /// 队列需要恢复秩序 /// 因为您无权访问任何索引(除非使用显式IList.this) /// 您不应该在不确切知道自己在做什么的情况下调用此函数。 /// /// 更改对象的索引 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); } /// /// 在不移除的情况下获取最小的对象 /// /// 最小的对象 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); } } } }