所以给出一些背景知识:
结果证明C#与我以前使用的其他语言略有不同。
这是我执行此操作时收到的错误消息:
PriorityQueue<Tuple<Point, double>> pq = new PriorityQueue<Tuple<Point, double>>();
错误CS0311:类型
System.Tuple<Tree.Point,double>' cannot be used as type parameter
T&#39;在泛型类型或方法中PriorityQueue.PriorityQueue<T>'. There is no implicit reference conversion from
System.Tuple&#39;至 `System.IComparable&GT;&#39;
我研究了很长一段时间,因为我是C#的新手,我不太明白为什么会这样。我想用Python编程可以让生活变得轻松。
我的优先级队列类如下所示:
public class PriorityQueue<T> where T : IComparable<T>
{
private List<T> dataHeap;
public PriorityQueue()
{
this.dataHeap = new List<T>();
}
public void Enqueue(T value)
{
this.dataHeap.Add(value);
BubbleUp();
}
public T Dequeue()
{
if (this.dataHeap.Count <= 0)
{
throw new InvalidOperationException("Cannot Dequeue from empty queue!");
}
T result = dataHeap[0];
int count = this.dataHeap.Count - 1;
dataHeap[0] = dataHeap[count];
dataHeap.RemoveAt(count);
ShiftDown();
return result;
}
private void BubbleUp()
{
int childIndex = dataHeap.Count - 1;
while (childIndex > 0)
{
int parentIndex = (childIndex - 1) / 2;
if (dataHeap[childIndex].CompareTo(dataHeap[parentIndex]) >= 0)
{
break;
}
SwapAt(childIndex, parentIndex);
childIndex = parentIndex;
}
}
private void ShiftDown()
{
int count = this.dataHeap.Count - 1;
int parentIndex = 0;
while (true)
{
int childIndex = parentIndex * 2 + 1;
if (childIndex > count)
{
break;
}
int rightChild = childIndex + 1;
if (rightChild <= count && dataHeap[rightChild].CompareTo(dataHeap[childIndex]) < 0)
{
childIndex = rightChild;
}
if (dataHeap[parentIndex].CompareTo(dataHeap[childIndex]) <= 0)
{
break;
}
SwapAt(parentIndex, childIndex);
parentIndex = childIndex;
}
}
public T Peek()
{
if (this.dataHeap.Count == 0)
{
throw new InvalidOperationException("Queue is empty.");
}
T frontItem = dataHeap[0];
return frontItem;
}
public int Count()
{
return dataHeap.Count;
}
/// <summary>Removes all elements from the queue.</summary>
public void Clear()
{
this.dataHeap.Clear();
}
public void CopyToArray(T[] array, int index)
{
if (array == null)
{
throw new ArgumentNullException("Array");
}
int length = array.Length;
if (index < 0 || index >= length)
{
throw new IndexOutOfRangeException("Index must be between zero and array length.");
}
if (length - index < this.dataHeap.Count-1)
{
throw new ArgumentException("Queue is bigger than array");
}
T[] data = this.dataHeap.ToArray();
Array.Copy(data, 0, array, index, data.Length);
}
public bool IsConsistent()
{
if (dataHeap.Count == 0)
{
return true;
}
int lastIndex = dataHeap.Count - 1;
for (int parentIndex = 0; parentIndex < dataHeap.Count; ++parentIndex)
{
int leftChildIndex = 2 * parentIndex + 1;
int rightChildIndex = 2 * parentIndex + 2;
if (leftChildIndex <= lastIndex && dataHeap[parentIndex].CompareTo(dataHeap[leftChildIndex]) > 0)
{
return false;
}
if (rightChildIndex <= lastIndex && dataHeap[parentIndex].CompareTo(dataHeap[rightChildIndex]) > 0)
{
return false;
}
}
return true;
}
private void SwapAt(int first,int second)
{
T value = dataHeap[first];
dataHeap[first] = dataHeap[second];
dataHeap[second] = value;
}
public override string ToString()
{
string queueString = string.Join(" ", dataHeap.ToArray());
return queueString;
}
}
My Point课程:
class Point : IComparable
{
private double x;
private double y;
public Point(double xCoord, double yCoord)
{
SetPoint(xCoord, yCoord);
}
~Point() {}
public int CompareTo(object obj)
{
if (obj == null) return 1;
Point p = obj as Point;
if (p != null)
return (this.x.CompareTo(p.x) & this.y.CompareTo(p.y));
else
throw new ArgumentException("Object is not a Point");
}
public static bool operator ==(Point a, Point b)
{
if (ReferenceEquals(a, null) || ReferenceEquals(b, null)) return true;
if (a[0] == b[0] && a[1] == b[1]) return true;
else return false;
}
public static bool operator !=(Point a, Point b)
{
if (ReferenceEquals(a, null) || ReferenceEquals(b, null)) return true;
if (a[0] != b[0] || a[1] != b[1]) return true;
else return false;
}
public double this[int index]
{
get
{
if (index == 0) return x;
else if (index == 1) return y;
else throw new System.IndexOutOfRangeException("index " + index + " is out of range");
}
set
{
if (index == 0) x = value;
else if (index == 1) y = value;
else throw new System.IndexOutOfRangeException("index " + index + " is out of range");
}
}
public void SetPoint(double xCoord, double yCoord)
{
x = xCoord;
y = yCoord;
}
public override string ToString()
{
return "(" + x + ", " + y + ")";
}
}
答案 0 :(得分:1)
我建议您删除T
上的约束,然后在IComparer<T>
的构造函数中使用明确的PriorityQueue
。如果没有提供,则现有构造函数可以提供Comparer<T>.Default
作为比较器。
然后,您需要在obj.CompareTo(other)
中将comp.Compare(obj, other)
更改为PriorityQueue
。
public class PriorityQueue<T>
{
private List<T> dataHeap;
private readonly IComparer<T> comp;
public PriorityQueue() : this(Comparer<T>.Default) {}
public PriorityQueue(IComparer<T> comp)
{
this.dataHeap = new List<T>();
this.comp = comp;
}
...
private void BubbleUp() {
if (this.comp.Compare(dataHeap[childIndex], dataHeap[parentIndex]) >= 0)
}
}