【问题标题】:creating a generic sort method创建通用排序方法
【发布时间】:2013-06-02 02:39:43
【问题描述】:

我正在学习泛型类型并想创建一个泛型 QuickSort 方法,问题是类不是协变的,代码无法编译。问题是使分区方法通用,我不知道该怎么做,任何指导将不胜感激。

public static void Swap<T>(ref T a, ref T b)
    {
        T temp = a;
        a = b;
        b = temp;
    }

    public static int Partition(int[] array, int mid)
    {
        int midPoint = mid,
            upperBound = array.Length - 1,
            lowerBound = 0;
        while (lowerBound != upperBound)
        {
            while (midPoint < upperBound)
            {
                if (array[midPoint] > array[upperBound])
                {
                    Swap<int>(ref array[midPoint], ref array[upperBound]);
                    midPoint = upperBound;
                    break;
                }
                upperBound--;
            }
            while (midPoint > lowerBound)
            {
                if (array[midPoint] < array[lowerBound])
                {
                    Swap<int>(ref array[midPoint], ref array[lowerBound]);
                    midPoint = lowerBound;
                    break;
                }
                lowerBound++;
            }
        }
        return midPoint;
    }

    public static void QuickSort(int[] array,int lower,int upper)
    {
        int mid = Partition(array, (lower + upper) / 2);

        if (upper <= lower)
        {
        }
        else
        {
            QuickSort(array, mid + 1, upper);
            QuickSort(array, lower, mid - 1);
        }
    }

【问题讨论】:

    标签: c# generics types


    【解决方案1】:

    第一步是真正使用泛型:

    void QuickSort<T>(T[] array, ...)
    

    int Partition<T>(T[] array, ...)
    

    Partition 中,从Swap 中删除通用参数。它会被编译器推断出来。

    但是,要使其正常工作,您需要将 T 限制为 IComparable&lt;T&gt;

    void QuickSort<T>(T[] array, ...) where T : IComparable<T>
    

    int Partition<T>(T[] array, ...) where T : IComparable<T>
    

    最后,您需要将“小于”和“大于”运算符替换为对CompareTo 的调用:

    if(array[midPoint].CompareTo(array[lowerBound]) < 0)
    

    if(array[midPoint].CompareTo(array[lowerBound]) > 0)
    

    【讨论】:

    • IMO 最好使用通用的 IComparable&lt;T&gt; 而不是 IComparable
    • @RobertRouhani 为什么更好,键入安全性或更多可用性?
    • 两者都有,而且性能更好。使用IComparable.CompareTo 表示如果T 是值类型,它将被装箱。使用 IComparable&lt;T&gt;.CompareTo 不会将值类型装箱。
    • @RobertRouhani:同意。我改了。
    【解决方案2】:

    您正在寻找的是将T 限制为实现IComparable&lt;T&gt; 的任何类型

    This MSDN article 很好地解释了 C# 中的通用约束。您的方法声明将如下所示:

    public static T Partition<T>(T[] array, int mid)
        where T : IComparable<T>
    {
        //code goes here
    }
    
    public static void QuickSort<T>(T[] array, int lower, int upper)
        where T : IComparable<T>
    {
        //code goes here
    }
    

    将您链接到MSDN article for IComparable&lt;T&gt; 也可能会有所帮助。无论您在哪里定期比较两个整数,都可以调用array[midPoint].CompareTo(array[upperBound]) &gt; 0。如果您将 CompareTo 的结果与 0 进行比较,所有的比较运算符都是相同的。

    还有一点需要注意的是,当您调用Swap&lt;int&gt;(... 时,编译器可以将类型推断为int,您可以简单地将其调用为Swap(...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-22
      • 1970-01-01
      • 2019-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多