2

我试图开发一个实现 IComparable 的通用类“MinHeap(T)”。当泛型为“int”或其他类“代码”时,它可以正常工作。更进一步并为 T 使用泛型类“Node(Code)”会导致下面提到的错误。

我可能太新了,不了解 IComparable 和 IComparable(T) 之间的细微差别。有人有想法吗?提前感谢您的帮助,LJ

public class MinHeap<T> where T : IComparable
{
...
}
public class Node<T> where T : IComparable
{
    T data
...
    public int CompareTo(object obj)
    {
        Node<T> otherNode = obj as Node<T>;
        return this.data.CompareTo(otherNode.data);
    }
...
}
public class Code : IComparable
{
    public int freq;
...
    public int CompareTo(object obj)
    {
        Code otherCode = obj as Code;
        return this.freq.CompareTo(otherCode.freq);
    }
}
static void Main(string[] args)
{
    MinHeap<int> hInt = new MaxHeap<int>(heapSeed); // works fine
    MinHeap<Code> hCode = new MinHeap<Code>(codeList); // works fine
...
    Node<Code>[] nodeCodeList = new Node<Code>[freqList.Length]; // ok        
    MinHeap<Node<Code>> h = new MinHeap<Node<Code>>(nodeCodeList); // Error
...
}

错误信息:

错误 2 类型“Algorithms.Node(Algorithms.Code)”不能用作泛型类型或方法“Algorithms.MinHeap(T)”中的类型参数“T”。没有从“Algorithms.Node(Algorithms.Code)”到“System.IComparable”的隐式引用转换。

4

3 回答 3

2

该类 Node<T>不实现IComparable。它只是对T.

看起来您已经尝试实现装饰器模式。也实现接口,然后将方法映射到装饰对象。

于 2013-07-30T13:02:02.860 回答
2

你可能最好定义你的泛型类,这样它就不需要类型来实现IComparable<T>。这就是.NET 泛型类的实现方式。他们将使用类型的默认比较,或使用IComparer<T>您传入的。例如,SortedList具有以下构造函数(以及其他构造函数):

SortedList<TKey, TValue>(); // uses default comparer for TKey
SortedList<TKey, TValue>(IComparer<T> comparer); // uses supplied comparer

很容易实现:

public class MinHeap<T>
{
    private IComparer<T> _comparer;

    public MinHeap<T>(IComparer<T> comp)
    {
        _comparer = comp;
    }

    public MinHeap<T>()
        : this(Comparer<T>.Default)
    {
    }
}

这样,您的客户可以使用MinHeap<T>来保存未实现的类的实例IComparable<T>

当你进行比较时,你打电话给_comparer.Compare(item1, item2)

另一方面,您的堆不需要节点。您可以在数组中实现二进制堆。例如,参见A Generic BinaryHeap Class

于 2013-07-30T13:27:39.577 回答
1

您应该在 Node 类中实现 IComparable 接口,如下所示:

  public class Node<T>: IComparable<Node<T>> // <- IComparable<Node<T>> implemented  
    where T: IComparable  {

    T data;

    ...

    #region IComparable<Node<T>> Members

    // interface implementation, not just a method
    public int CompareTo(Node<T> other) {
      // Let us be accurate with possible nulls:  
      if (Object.ReferenceEquals(null, other))
        return 1; // <- or -1 if you think it's right
      else if (Object.ReferenceEquals(data, other.data))   
        return 0;
      else if (Object.ReferenceEquals(null, data))   
        return -1; // <- or 1 if you think it's right

      return data.CompareTo(other.data);
    }

    #endregion IComparable<Node<T>> Members
  }

根据最小堆的算法,您可能还必须在 MinHeap 类中实现 IComparable>

于 2013-07-30T13:10:22.340 回答