UnityMol  0.9.6-875
UnityMol viewer / In developement
PriorityQueue.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections;
3 
4 namespace BenTools.Data
5 {
6  public interface IPriorityQueue : ICollection, ICloneable, IList
7  {
8  int Push(object O);
9  object Pop();
10  object Peek();
11  void Update(int i);
12  }
13  public class BinaryPriorityQueue : IPriorityQueue, ICollection, ICloneable, IList
14  {
15  protected ArrayList InnerList = new ArrayList();
16  protected IComparer Comparer;
17 
18  #region contructors
19  public BinaryPriorityQueue() : this(System.Collections.Comparer.Default)
20  {}
21  public BinaryPriorityQueue(IComparer c)
22  {
23  Comparer = c;
24  }
25  public BinaryPriorityQueue(int C) : this(System.Collections.Comparer.Default,C)
26  {}
27  public BinaryPriorityQueue(IComparer c, int Capacity)
28  {
29  Comparer = c;
30  InnerList.Capacity = Capacity;
31  }
32 
33  protected BinaryPriorityQueue(ArrayList Core, IComparer Comp, bool Copy)
34  {
35  if(Copy)
36  InnerList = Core.Clone() as ArrayList;
37  else
38  InnerList = Core;
39  Comparer = Comp;
40  }
41 
42  #endregion
43  protected void SwitchElements(int i, int j)
44  {
45  object h = InnerList[i];
46  InnerList[i] = InnerList[j];
47  InnerList[j] = h;
48  }
49 
50  protected virtual int OnCompare(int i, int j)
51  {
52  return Comparer.Compare(InnerList[i],InnerList[j]);
53  }
54 
55  #region public methods
56  public int Push(object O)
62  {
63  int p = InnerList.Count,p2;
64  InnerList.Add(O); // E[p] = O
65  do
66  {
67  if(p==0)
68  break;
69  p2 = (p-1)/2;
70  if(OnCompare(p,p2)<0)
71  {
72  SwitchElements(p,p2);
73  p = p2;
74  }
75  else
76  break;
77  }while(true);
78  return p;
79  }
80 
85  public object Pop()
86  {
87  object result = InnerList[0];
88  int p = 0,p1,p2,pn;
89  InnerList[0] = InnerList[InnerList.Count-1];
90  InnerList.RemoveAt(InnerList.Count-1);
91  do
92  {
93  pn = p;
94  p1 = 2*p+1;
95  p2 = 2*p+2;
96  if(InnerList.Count>p1 && OnCompare(p,p1)>0) // links kleiner
97  p = p1;
98  if(InnerList.Count>p2 && OnCompare(p,p2)>0) // rechts noch kleiner
99  p = p2;
100 
101  if(p==pn)
102  break;
103  SwitchElements(p,pn);
104  }while(true);
105  return result;
106  }
107 
116  public void Update(int i)
117  {
118  int p = i,pn;
119  int p1,p2;
120  do // aufsteigen
121  {
122  if(p==0)
123  break;
124  p2 = (p-1)/2;
125  if(OnCompare(p,p2)<0)
126  {
127  SwitchElements(p,p2);
128  p = p2;
129  }
130  else
131  break;
132  }while(true);
133  if(p<i)
134  return;
135  do // absteigen
136  {
137  pn = p;
138  p1 = 2*p+1;
139  p2 = 2*p+2;
140  if(InnerList.Count>p1 && OnCompare(p,p1)>0) // links kleiner
141  p = p1;
142  if(InnerList.Count>p2 && OnCompare(p,p2)>0) // rechts noch kleiner
143  p = p2;
144 
145  if(p==pn)
146  break;
147  SwitchElements(p,pn);
148  }while(true);
149  }
150 
155  public object Peek()
156  {
157  if(InnerList.Count>0)
158  return InnerList[0];
159  return null;
160  }
161 
162  public bool Contains(object value)
163  {
164  return InnerList.Contains(value);
165  }
166 
167  public void Clear()
168  {
169  InnerList.Clear();
170  }
171 
172  public int Count
173  {
174  get
175  {
176  return InnerList.Count;
177  }
178  }
179  IEnumerator IEnumerable.GetEnumerator()
180  {
181  return InnerList.GetEnumerator();
182  }
183 
184  public void CopyTo(Array array, int index)
185  {
186  InnerList.CopyTo(array,index);
187  }
188 
189  public object Clone()
190  {
191  return new BinaryPriorityQueue(InnerList,Comparer,true);
192  }
193 
194  public bool IsSynchronized
195  {
196  get
197  {
198  return InnerList.IsSynchronized;
199  }
200  }
201 
202  public object SyncRoot
203  {
204  get
205  {
206  return this;
207  }
208  }
209  #endregion
210  #region explicit implementation
211  bool IList.IsReadOnly
212  {
213  get
214  {
215  return false;
216  }
217  }
218 
219  object IList.this[int index]
220  {
221  get
222  {
223  return InnerList[index];
224  }
225  set
226  {
227  InnerList[index] = value;
228  Update(index);
229  }
230  }
231 
232  int IList.Add(object o)
233  {
234  return Push(o);
235  }
236 
237  void IList.RemoveAt(int index)
238  {
239  throw new NotSupportedException();
240  }
241 
242  void IList.Insert(int index, object value)
243  {
244  throw new NotSupportedException();
245  }
246 
247  void IList.Remove(object value)
248  {
249  throw new NotSupportedException();
250  }
251 
252  int IList.IndexOf(object value)
253  {
254  throw new NotSupportedException();
255  }
256 
257  bool IList.IsFixedSize
258  {
259  get
260  {
261  return false;
262  }
263  }
264 
266  {
267  return new BinaryPriorityQueue(ArrayList.Synchronized(P.InnerList),P.Comparer,false);
268  }
270  {
271  return new BinaryPriorityQueue(ArrayList.ReadOnly(P.InnerList),P.Comparer,false);
272  }
273  #endregion
274  }
275 }
void CopyTo(Array array, int index)
virtual int OnCompare(int i, int j)
BinaryPriorityQueue(ArrayList Core, IComparer Comp, bool Copy)
BinaryPriorityQueue(IComparer c, int Capacity)
object Pop()
Get the smallest object and remove it.
void Update(int i)
Notify the PQ that the object at position i has changed and the PQ needs to restore order...
static BinaryPriorityQueue ReadOnly(BinaryPriorityQueue P)
void SwitchElements(int i, int j)
static BinaryPriorityQueue Syncronized(BinaryPriorityQueue P)
object Peek()
Get the smallest object without removing it.