.NET中是否有排序的集合类型?

时间:2008-10-13 02:05:47

标签: c# .net sorting containers

我正在寻找一个能够保持所有物品整齐的容器。我查看了SortedList,但这需要一个单独的密钥,并且不允许重复密钥。我也可以使用未分类的容器,并在每次插入后显式排序。

用法:

  • 偶尔插入
  • 按顺序频繁遍历
  • 理想情况下,不使用与实际对象分开的键,使用比较函数进行排序。
  • 需要对等效对象进行稳定的排序,但不是必需的。
  • 不需要随机访问。

我意识到我可以建立一个平衡的树结构,我只是想知道框架是否已经包含这样的野兽。

7 个答案:

答案 0 :(得分:20)

您可能需要查看Wintellect Power Collections。它可以在CodePlex上获得,并且包含很多非常有用的集合。项目中的OrderedBag集合正是您正在寻找的。它本质上使用red-black tree来提供非常有效的排序。

答案 1 :(得分:12)

只需要EBarr's comment作为答案,自.NET 4.0起就有SortedSet<T>。当然它是一个集合,这意味着你不能有重复。

答案 2 :(得分:3)

我会扩展你自己的列表类,如你所提到的,只需在每次插入后进行排序。由于您的插入很少,因此性能损失最小,并且在任何情况下快速排序几乎排序的列表。扩展通用列表并覆盖Add方法以立即排序。如果性能成为问题,您可以插入到位以节省一些时间。此外,您可以对插入进行排队,以便为要插入的所有值执行单次遍历插入。

答案 3 :(得分:3)

如果您只想坚持使用标准集合,那么Sort(IComparer<>)类的List<>函数通常会被忽略。您需要做的就是为对象创建合适的Comparer<>。例如:

public class PositionDateComparer : IComparer<VehiclePosition>
{
    public int Compare(VehiclePosition x, VehiclePosition y)
    {
        if (x.DateTime == DateTime.MinValue)
        {
            if (y.DateTime == DateTime.MinValue)
            {
                // If x is null and y is null, they're
                // equal. 
                return 0;
            }

            // If x is null and y is not null, y
            // is greater. 
            return -1;
        }

        // If x is not null...
        //
        if (y.DateTime == DateTime.MinValue)
        // ...and y is null, x is greater.
        {
            return 1;
        }

        // ...and y is not null, compare the dates
        //
        if (x.DateTime == y.DateTime)
        {
            // x and y are equal
            return 0;
        }

        if (x.DateTime > y.DateTime)
        {
            // x is greater
            return 1;
        }

        // y is greater
        return -1;
    }
}

然后只需在访问列表之前对列表进行排序即可执行vehiclePositionsList.Sort(new PositionDateComparer())。我意识到这可能不像每次添加新对象时自动排序的容器那么简单,但对于许多人(比如我!)而言,这可能足以成功完成工作而无需任何其他库。

答案 4 :(得分:2)

正如我今天早些时候提到的hereC5 Generic Collection Library有适合您的容器。

答案 5 :(得分:-1)

如果密钥也是对象的属性,您可以尝试System.Collections.ObjectModel.KeyedCollection<TKey, TItem>。它是一个抽象类,但如果你的键只是项目的一个属性,那么它的衍生起来非常简单。

答案 6 :(得分:-15)

这是我在VB6中用来按字母顺序排序的旧技巧:使用System.Windows.Forms ListBox对象,并将其“Sorted”属性设置为true。在C#中,您可以将任何对象插入到列表框中,它将按照ToString()值的字母顺序对对象进行排序:

用于课程模块:


使用System.Windows.Forms;

    static void Main(string[] args)
    {
        ListBox sortedList = new ListBox();
        sortedList.Sorted = true;

        sortedList.Items.Add("foo");
        sortedList.Items.Add("bar");
        sortedList.Items.Add(true);
        sortedList.Items.Add(432); 

        foreach (object o in sortedList.Items)
        {
            Console.WriteLine(o);
        }

        Console.ReadKey();
    }

这将显示:

432
酒吧
FOO