C#实现优先队列模板
C#并不提供优先队列这个API。所以我们要自己去实现C#的优先队列。这里我参考了知乎这位作者的优先队列实现。(不过他用的是C++,我只是单纯的转换为C#而言)文章链接:https://zhuanlan.zhihu.com/p/35314095。具体的方法可以直接去看知乎的文章。我这里就直接给出C#的实现。(这里我根据自己的需求加了一些东西,你们也可以看文章中的代码改造然后根据自己的需求去修改)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
| using System; using System.Linq;
namespace ConsoleApp1 { public class PriorityQueue<T> where T : IComparable { private int count; private T[] queue; private Func<T, T, bool> cmp; private int capacity; private const int DefalutCapacity = 100;
public int Count { get { return count; } }
public PriorityQueue() : this(DefalutCapacity, null) { }
public PriorityQueue(Func<T, T, bool> cmp) : this(DefalutCapacity, cmp) { }
public PriorityQueue(int capacity, Func<T, T, bool> cmp) { this.cmp = cmp; this.capacity = capacity; queue = new T[capacity]; count = 0; }
~ PriorityQueue() {
}
public T Peek() { if(count == 0) { throw new InvalidOperationException("队列为空"); } return queue[1]; }
public void Enqueue(T val) { count++; if(capacity == count) { if (int.MaxValue == capacity) { throw new ArgumentOutOfRangeException("count"); } if(int.MaxValue - capacity < capacity) { capacity = int.MaxValue; } else { capacity *= 2; } T[] tmp = new T[capacity]; for (int i = 0; i < count; i++) { tmp[i] = queue[i]; } queue = tmp; } queue[count] = val; Swim(count); }
public T Dequeue() { if(count == 0) { throw new InvalidOperationException("队列为空"); } T res = queue[1]; queue[1] = queue[count]; count--; Sink(1); return res; }
public bool isEmpty() { return count == 0; }
public T[] ToArray() { return queue.ToArray(); }
private void Swim(int n) { while (n > 1) { T val1 = queue[n]; T val2 = queue[n >> 1]; if(CompareFun(val1,val2)) { queue[n] = val2; queue[n >> 1] = val1; } n = n >> 1; } }
private void Sink(int n) { while(2 * n <= count) { int t = 2 * n; if (t < count && CompareFun(queue[t + 1], queue[t])) t++; if (CompareFun(queue[t], queue[n])) { T tmp = queue[t]; queue[t] = queue[n]; queue[n] = tmp; n = t; } else break; } }
private bool CompareFun(T val1, T val2) { if (cmp != null) { return cmp(val1, val2); } return val1.CompareTo(val2) > 0; } } }
|