Free cookie consent management tool by TermsFeed Policy Generator

source: branches/RoutePlanning/HeuristicLab.Algorithms.GraphRouting/3.3/Utilities/PriorityQueue.cs @ 10343

Last change on this file since 10343 was 8516, checked in by spimming, 12 years ago

#1894:

  • solution restructured
  • removed obsolete and outdated parts
File size: 4.4 KB
Line 
1
2using System;
3using System.Collections;
4using System.Collections.Generic;
5namespace HeuristicLab.Algorithms.GraphRouting.Utilities {
6  public class PriorityQueue<TPriority, TValue> : ICollection<KeyValuePair<TPriority, TValue>> {
7    private List<KeyValuePair<TPriority, TValue>> heap;
8    private Dictionary<TValue, KeyValuePair<TPriority, TValue>> values;
9    private IComparer<TPriority> comparer;
10
11    #region Constructors
12
13    public PriorityQueue(IComparer<TPriority> comparer) {
14      if (comparer == null)
15        throw new ArgumentNullException();
16
17      heap = new List<KeyValuePair<TPriority, TValue>>();
18      values = new Dictionary<TValue, KeyValuePair<TPriority, TValue>>();
19      this.comparer = comparer;
20    }
21
22    #endregion
23
24    #region Priority queue methods
25
26    public void Enqueue(TPriority priority, TValue value) {
27      Insert(priority, value);
28    }
29
30    public KeyValuePair<TPriority, TValue> Dequeue() {
31      if (Count != 0) {
32        KeyValuePair<TPriority, TValue> item = heap[0];
33        RemoveRoot();
34        return item;
35      } else {
36        throw new InvalidOperationException("Priority queue is empty");
37      }
38    }
39
40    public TValue DequeueValue() {
41      return Dequeue().Value;
42    }
43
44    #endregion
45
46    #region ICollection members
47
48    public void Add(KeyValuePair<TPriority, TValue> item) {
49      Enqueue(item.Key, item.Value);
50    }
51
52    public void Clear() {
53      heap.Clear();
54      values.Clear();
55    }
56
57    public bool Contains(KeyValuePair<TPriority, TValue> item) {
58      return heap.Contains(item);
59    }
60
61    public bool Contains(TValue value) {
62      return values.ContainsKey(value);
63    }
64
65    public void CopyTo(KeyValuePair<TPriority, TValue>[] array, int arrayIndex) {
66      heap.CopyTo(array, arrayIndex);
67    }
68
69    public int Count {
70      get { return heap.Count; }
71    }
72
73    public bool IsReadOnly {
74      get { return false; }
75    }
76
77    public bool Remove(KeyValuePair<TPriority, TValue> item) {
78      int idx = heap.IndexOf(item);
79      if (idx < 0) {
80        return false;
81      }
82
83      values.Remove(item.Value);
84
85      heap[idx] = heap[heap.Count - 1];
86      heap.RemoveAt(heap.Count - 1);
87
88      HeapUp(idx);
89      HeapDown(idx);
90
91      return true;
92    }
93
94    public bool Remove(TValue value) {
95      KeyValuePair<TPriority, TValue> item = values[value];
96      return Remove(item);
97    }
98
99    #endregion
100
101    #region IEnumerable Members
102
103    public IEnumerator<KeyValuePair<TPriority, TValue>> GetEnumerator() {
104      return heap.GetEnumerator();
105    }
106
107    IEnumerator IEnumerable.GetEnumerator() {
108      return this.GetEnumerator();
109    }
110
111    #endregion
112
113    #region Private methods
114
115    private void SwapElements(int pos1, int pos2) {
116      KeyValuePair<TPriority, TValue> element = heap[pos1];
117      heap[pos1] = heap[pos2];
118      heap[pos2] = element;
119    }
120
121    private void Insert(TPriority priority, TValue value) {
122      KeyValuePair<TPriority, TValue> element = new KeyValuePair<TPriority, TValue>(priority, value);
123      heap.Add(element);
124      values.Add(value, element);
125
126      HeapUp(heap.Count - 1);
127    }
128
129    private void RemoveRoot() {
130      if (heap.Count <= 1) {
131        heap.Clear();
132        values.Clear();
133      } else {
134        KeyValuePair<TPriority, TValue> item = heap[0];
135        values.Remove(item.Value);
136
137        heap[0] = heap[heap.Count - 1];
138        heap.RemoveAt(heap.Count - 1);
139
140        HeapDown(0);
141      }
142    }
143
144    private void HeapUp(int pos) {
145      if (pos < heap.Count) {
146        while (pos > 0) {
147          int parent = (pos - 1) / 2;
148          if (comparer.Compare(heap[parent].Key, heap[pos].Key) > 0) {
149            SwapElements(parent, pos);
150            pos = parent;
151          } else {
152            break;
153          }
154        }
155      }
156    }
157
158    private void HeapDown(int pos) {
159      while (true) {
160        int smallest = pos;
161        int left = 2 * pos + 1;
162        int right = 2 * pos + 2;
163        if (left < heap.Count && comparer.Compare(heap[smallest].Key, heap[left].Key) > 0) {
164          smallest = left;
165        }
166        if (right < heap.Count && comparer.Compare(heap[smallest].Key, heap[right].Key) > 0) {
167          smallest = right;
168        }
169
170        if (smallest != pos) {
171          SwapElements(smallest, pos);
172          pos = smallest;
173        } else {
174          break;
175        }
176      }
177    }
178
179    #endregion
180  }
181}
Note: See TracBrowser for help on using the repository browser.