// // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR // PURPOSE. IT CAN BE DISTRIBUTED FREE OF CHARGE AS LONG AS THIS HEADER // REMAINS UNCHANGED. // // Email: gustavo_franco@hotmail.com // // Copyright (C) 2006 Franco, Gustavo // using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; namespace AStar { #region Interfaces [Author("Franco, Gustavo")] public interface IPriorityQueue { #region Methods int Push(T item); T Pop(); T Peek(); void Update(int i); #endregion } #endregion [Author("Franco, Gustavo")] public class PriorityQueueB : IPriorityQueue { #region Variables Declaration protected List InnerList = new List(); protected IComparer mComparer; #endregion #region Contructors public PriorityQueueB() { mComparer = Comparer.Default; } public PriorityQueueB(IComparer comparer) { mComparer = comparer; } public PriorityQueueB(IComparer comparer, int capacity) { mComparer = comparer; InnerList.Capacity = capacity; } #endregion #region Methods protected void SwitchElements(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]); } /// /// Push an object onto the PQ /// /// The new object /// The index in the list where the object is _now_. This will change when objects are taken from or put onto the PQ. public int Push(T item) { int p = InnerList.Count,p2; InnerList.Add(item); // E[p] = O do { if(p==0) break; p2 = (p-1)/2; if(OnCompare(p,p2)<0) { SwitchElements(p,p2); p = p2; } else break; }while(true); return p; } /// /// Get the smallest object and remove it. /// /// The smallest object public T Pop() { T result = InnerList[0]; int p = 0,p1,p2,pn; InnerList[0] = InnerList[InnerList.Count-1]; InnerList.RemoveAt(InnerList.Count-1); do { pn = p; p1 = 2*p+1; p2 = 2*p+2; if(InnerList.Count>p1 && OnCompare(p,p1)>0) // links kleiner p = p1; if(InnerList.Count>p2 && OnCompare(p,p2)>0) // rechts noch kleiner p = p2; if(p==pn) break; SwitchElements(p,pn); }while(true); return result; } /// /// Notify the PQ that the object at position i has changed /// and the PQ needs to restore order. /// Since you dont have access to any indexes (except by using the /// explicit IList.this) you should not call this function without knowing exactly /// what you do. /// /// The index of the changed object. 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) { SwitchElements(p,p2); p = p2; } else break; }while(true); if(pp1 && OnCompare(p,p1)>0) // links kleiner p = p1; if(InnerList.Count>p2 && OnCompare(p,p2)>0) // rechts noch kleiner p = p2; if(p==pn) break; SwitchElements(p,pn); }while(true); } /// /// Get the smallest object without removing it. /// /// The smallest object public T Peek() { if(InnerList.Count>0) return InnerList[0]; return default(T); } public void Clear() { InnerList.Clear(); } public int Count { get{ return InnerList.Count; } } public void RemoveLocation(T item) { int index = -1; for(int i=0; i