使用类型T对列表进行排序

3
我是一名有用的助手,可以帮您进行文本翻译。

我正在尝试使用冒泡排序来对类型为<T>的列表进行排序。不幸的是,我在比较未知类型的对象时遇到了问题。

我目前尝试过的方法:

public static void BubbleSort<T>(this List<T> array)
{
    for (int i = (array.Count - 1); i >= 0; i--)
    {
        for (int j = 1; j <= i; j++)
        {
            if (array[j - 1] > array[j]) // issue here
            {
                var temp = array[j - 1];
                array[j - 1] = array[j];
                array[j] = temp;
            }
        }
    }
}

3
考虑增加一个IComparer<T>参数,或者使用Comparer<T>.Default。强烈建议重命名您的参数,因为List<T>不是数组。(我假设这只是为了教育目的而已?) - Jon Skeet
@Sriram 我猜他正在学习冒泡排序的工作原理。 - Carra
@Sriram Sakthivel 我敢打赌,如果你需要一个方法来判断List<T>是否已排序,你会回到这里的 :) - fubo
如果您想进行自定义排序,则更好的方法是使用 IComparable<T> 为类启用比较功能,并创建一个实现 IComparer 接口的新类以进行自定义筛选。 - Arjun Kamlakar
@HenkHolterman 我仍然会编写自己的版本,但除非它表现不佳,否则我几乎不会在生产中使用它,因为 .Net 已经为我提供了一个版本。 - Sriram Sakthivel
显示剩余5条评论
3个回答

14

如果您不需要除默认比较以外的任何内容,可以使用:

// TODO: Rename the parameter...
public static void BubbleSort<T>(this List<T> array)
{
    IComparer<T> comparer = Comparer<T>.Default;
    ...
    if (comparer.Compare(array[j - 1], array[j]) > 0)
    {
        ...
    }
}

或者允许自定义比较:

public static void BubbleSort<T>(this List<T> array, IComparer<T> comparer)
{
    ...
    if (comparer.Compare(array[j - 1], array[j]) > 0)
    {
        ...
    }
}

或者将 T 限制为实现 IComparable<T> 的类型:

public static void BubbleSort<T>(this List<T> array) where T : IComparable<T>
{
    ...
    if (array[j - 1].CompareTo(array[j]) > 0)
    {
        ...
    }
}

请注意,在这里添加对 T 约束意味着任何 调用者 都需要知道使用的类型参数需要实现 IComparable<T> 接口... 这使得在编译时更加安全,但代价是约束会向上传递到调用链中。(一种选择是允许有约束但没有比较器的版本和有比较器却没有约束的版本。)

8

不可以使用 > 来比较两个 T 值。

首先,您需要在 T 上添加一个约束条件:

public static void BubbleSort<T>(this List<T> array)
   where T : IComparable<T>
{
}

然后您可以调用。
//if (array[j - 1] > array[j]) // issue here
if (array[j - 1].CompareTo(array[j]) > 0) // solved

1
在扩展方法显式地放置类型约束以使其可比较方面得到加强,这是一个不错的想法。 - Daniel Park

0

有一个可能性是要求 T 实现 IComparable 或者 IComparable<T> 接口,如 此处此处 所定义。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接