有时可能需要一种操作与Queue类似的数据结构,但要根据一种特定的顺序返回对象。向这个队列增加对象时,要根据其优先级放入队列的适当位置。在从队列获取对象时,队列可以根据优先级返回最高或最低的元素。
范型优先队列类:
public
class
PriorityQueue
<
T
>
: IEnumerable, ICloneable
... {
public PriorityQueue() ...{}
//指定自定义的比较接口
public PriorityQueue(IComparer<T> icomparer)
...{
specialComparer = icomparer;
}
protected List<T> internalQueue = new List<T>();
protected IComparer<T> specialComparer = null;
public int Count
...{
get ...{return (internalQueue.Count);}
}
public void Clear()
...{
internalQueue.Clear();
}
public object Clone()
...{
// Make a new PQ and give it the same comparer
PriorityQueue<T> newPQ = new PriorityQueue<T>(specialComparer);
newPQ.CopyTo(internalQueue.ToArray(),0);
return newPQ;
}
public int IndexOf(T item)
...{
return (internalQueue.IndexOf(item));
}
public bool Contains(T item)
...{
return (internalQueue.Contains(item));
}
public int BinarySearch(T item)
...{
return (internalQueue.BinarySearch(item, specialComparer));
}
public bool Contains(T item, IComparer<T> specialComparer)
...{
if (internalQueue.BinarySearch(item, specialComparer) >= 0)
...{
return (true);
}
else
...{
return (false);
}
}
public void CopyTo(T[] array, int index)
...{
internalQueue.CopyTo(array, index);
}
public virtual T[] ToArray()
...{
return (internalQueue.ToArray());
}
public virtual void TrimExcess()
...{
internalQueue.TrimExcess();
}
public void Enqueue(T item)
...{
internalQueue.Add(item);
internalQueue.Sort(specialComparer);
}
public T DequeueSmallest()
...{
T item = internalQueue[0];
internalQueue.RemoveAt(0);
return (item);
}
public T DequeueLargest()
...{
T item = internalQueue[internalQueue.Count - 1];
internalQueue.RemoveAt(internalQueue.Count - 1);
return (item);
}
public T PeekSmallest()
...{
return (internalQueue[0]);
}
public T PeekLargest()
...{
return (internalQueue[internalQueue.Count - 1]);
}
public IEnumerator GetEnumerator()
...{
return (internalQueue.GetEnumerator());
}
}
... {
public PriorityQueue() ...{}
//指定自定义的比较接口
public PriorityQueue(IComparer<T> icomparer)
...{
specialComparer = icomparer;
}
protected List<T> internalQueue = new List<T>();
protected IComparer<T> specialComparer = null;
public int Count
...{
get ...{return (internalQueue.Count);}
}
public void Clear()
...{
internalQueue.Clear();
}
public object Clone()
...{
// Make a new PQ and give it the same comparer
PriorityQueue<T> newPQ = new PriorityQueue<T>(specialComparer);
newPQ.CopyTo(internalQueue.ToArray(),0);
return newPQ;
}
public int IndexOf(T item)
...{
return (internalQueue.IndexOf(item));
}
public bool Contains(T item)
...{
return (internalQueue.Contains(item));
}
public int BinarySearch(T item)
...{
return (internalQueue.BinarySearch(item, specialComparer));
}
public bool Contains(T item, IComparer<T> specialComparer)
...{
if (internalQueue.BinarySearch(item, specialComparer) >= 0)
...{
return (true);
}
else
...{
return (false);
}
}
public void CopyTo(T[] array, int index)
...{
internalQueue.CopyTo(array, index);
}
public virtual T[] ToArray()
...{
return (internalQueue.ToArray());
}
public virtual void TrimExcess()
...{
internalQueue.TrimExcess();
}
public void Enqueue(T item)
...{
internalQueue.Add(item);
internalQueue.Sort(specialComparer);
}
public T DequeueSmallest()
...{
T item = internalQueue[0];
internalQueue.RemoveAt(0);
return (item);
}
public T DequeueLargest()
...{
T item = internalQueue[internalQueue.Count - 1];
internalQueue.RemoveAt(internalQueue.Count - 1);
return (item);
}
public T PeekSmallest()
...{
return (internalQueue[0]);
}
public T PeekLargest()
...{
return (internalQueue[internalQueue.Count - 1]);
}
public IEnumerator GetEnumerator()
...{
return (internalQueue.GetEnumerator());
}
}
实现了比较接口的字符串比较程序:
public
class
CompareStrLen
<
T
>
: IComparer
<
T
>
where T: IComparable < T >
... {
public int Compare(T obj1, T obj2)
...{
int result = 0;
if ((obj1 is string) && (obj2 is string))
...{
result = CompareStrings(obj1 as string, obj2 as string);
}
else
...{
// Default to the objects comparison algorithm
result = Compare(obj1, obj2);
}
return (result);
}
private int CompareStrings(string str1, string str2)
...{
if (str1.Length == str2.Length)
...{
return (0);
}
else if (str1.Length > str2.Length)
...{
return (1);
}
else
...{
return (-1);
}
}
public bool Equals(T item1, T item2)
...{
return (item1.Equals(item2));
}
public int GetHashCode(T obj)
...{
return (obj.GetHashCode());
}
}
where T: IComparable < T >
... {
public int Compare(T obj1, T obj2)
...{
int result = 0;
if ((obj1 is string) && (obj2 is string))
...{
result = CompareStrings(obj1 as string, obj2 as string);
}
else
...{
// Default to the objects comparison algorithm
result = Compare(obj1, obj2);
}
return (result);
}
private int CompareStrings(string str1, string str2)
...{
if (str1.Length == str2.Length)
...{
return (0);
}
else if (str1.Length > str2.Length)
...{
return (1);
}
else
...{
return (-1);
}
}
public bool Equals(T item1, T item2)
...{
return (item1.Equals(item2));
}
public int GetHashCode(T obj)
...{
return (obj.GetHashCode());
}
}
测试程序:
public
static
void
CreatePriorityQueue()
... {
// Create List of messages
List<string> msgs = new List<string>();
msgs.Add("foo");
msgs.Add("This is a longer message.");
msgs.Add("bar");
msgs.Add(@"Message with odd characters
!@#$%^&*()_+=-0987654321~|}{[]/;:?/>.<,");
msgs.Add(@"<
>");
msgs.Add("<text>one</text><text>two</text><text>three</text>" +
"<text>four</text>");
msgs.Add("");
msgs.Add("1234567890");
// Create a Priority Queue with the appropriate comparer
CompareStrLen<string> comparer = new CompareStrLen<string>();
PriorityQueue<string> pqueue = new PriorityQueue<string>(comparer);
// Add all messages from the List to the priority queue
foreach (string msg in msgs)
...{
pqueue.Enqueue(msg);
}
// Display messages in the queue in order of priority
foreach (string msg in pqueue)
...{
Console.WriteLine("Msg: " + msg);
}
Console.WriteLine("pqueue.Count == " + pqueue.Count);
//pqueue.Clear();
//Console.WriteLine("pqueue.Count == " + pqueue.Count);
Console.WriteLine("pqueue.IndexOf('bar') == " + pqueue.IndexOf("bar"));
Console.WriteLine("pqueue.IndexOf('_bar_') == " + pqueue.IndexOf("_bar_"));
Console.WriteLine("pqueue.Contains('bar') == " + pqueue.Contains("bar"));
Console.WriteLine("pqueue.Contains('_bar_') == " + pqueue.Contains("_bar_"));
Console.WriteLine("pqueue.BinarySearch('bar') == " + pqueue.BinarySearch("bar"));
Console.WriteLine("pqueue.BinarySearch('_bar_') == " + pqueue.BinarySearch("_bar_"));
// Dequeue messages starting with the smallest
int currCount = pqueue.Count;
for (int index = 0; index < currCount; index++)
...{
// In order to dequeue messages starting with the largest uncomment
// the following line and comment the following lines that
// dequeue starting with the smallest message
//Console.WriteLine("pqueue.DequeueLargest(): " +
// pqueue.DequeueLargest().ToString());
Console.WriteLine("pqueue.DequeueSmallest(): " +
pqueue.DequeueSmallest().ToString());
}
}
... {
// Create List of messages
List<string> msgs = new List<string>();
msgs.Add("foo");
msgs.Add("This is a longer message.");
msgs.Add("bar");
msgs.Add(@"Message with odd characters
!@#$%^&*()_+=-0987654321~|}{[]/;:?/>.<,");
msgs.Add(@"<
>");
msgs.Add("<text>one</text><text>two</text><text>three</text>" +
"<text>four</text>");
msgs.Add("");
msgs.Add("1234567890");
// Create a Priority Queue with the appropriate comparer
CompareStrLen<string> comparer = new CompareStrLen<string>();
PriorityQueue<string> pqueue = new PriorityQueue<string>(comparer);
// Add all messages from the List to the priority queue
foreach (string msg in msgs)
...{
pqueue.Enqueue(msg);
}
// Display messages in the queue in order of priority
foreach (string msg in pqueue)
...{
Console.WriteLine("Msg: " + msg);
}
Console.WriteLine("pqueue.Count == " + pqueue.Count);
//pqueue.Clear();
//Console.WriteLine("pqueue.Count == " + pqueue.Count);
Console.WriteLine("pqueue.IndexOf('bar') == " + pqueue.IndexOf("bar"));
Console.WriteLine("pqueue.IndexOf('_bar_') == " + pqueue.IndexOf("_bar_"));
Console.WriteLine("pqueue.Contains('bar') == " + pqueue.Contains("bar"));
Console.WriteLine("pqueue.Contains('_bar_') == " + pqueue.Contains("_bar_"));
Console.WriteLine("pqueue.BinarySearch('bar') == " + pqueue.BinarySearch("bar"));
Console.WriteLine("pqueue.BinarySearch('_bar_') == " + pqueue.BinarySearch("_bar_"));
// Dequeue messages starting with the smallest
int currCount = pqueue.Count;
for (int index = 0; index < currCount; index++)
...{
// In order to dequeue messages starting with the largest uncomment
// the following line and comment the following lines that
// dequeue starting with the smallest message
//Console.WriteLine("pqueue.DequeueLargest(): " +
// pqueue.DequeueLargest().ToString());
Console.WriteLine("pqueue.DequeueSmallest(): " +
pqueue.DequeueSmallest().ToString());
}
}