c#中的排序集合

  • Post author:
  • Post category:其他




有序集

具体到一种结构时,如果仍然称为集,那么这种结构一般是不允许有重复值的。

集在数学里具有这样的定义。我们一般称数据集合的时候,只是叫顺口了,没有严格按照数学定义说。

有序集基于二分查找,相较于普通的无序集速度更快(更数组和列表这种直接用索引的还是没得比)。

但是在添加和删除元素的时候,有更大的成本。

另外他的排序只在添加元素时进行一次,对已经加进来的数据再做更改,可能导致严重问题。

class Student : IComparable<Student>
{
    public int id;
    public int age;
    public string name;

    public int CompareTo(Student? other) => id.CompareTo(other.id);
}
SortedSet<Student> sortedSet = new SortedSet<Student>();

有序集只能储存实现了排序接口(IComparable泛型版本)的类型。否则需要为其指定比较器。

比较器是一个实现了比较器接口(IComparer泛型版本)的实例,也就是说你需要新建一个类。



添加元素

sortedSet.Add(new Student() {id=12,age=18,name="小明" });
sortedSet.Add(new Student() {id=12,age=16,name="小红" });

Add方法可以将元素添加到有序集中。集不能有并列值。

如果添加的元素在顺序上和现有元素具有并列关系,那么会添加失败。

不过这不会报错,Add方法会返回一个bool值,指示这次添加是否成功。



添加序列

UnionWith方法的字面是获得自己和他的并集。

实际效果是把目标序列整个尝试添加到自己身上。

Student[] stuArr = { new Student() { id = 11, age = 12, name = "小绿" }, new Student() { id = 3, age = 18, name = "小蓝" } };
sortedSet.UnionWith(stuArr);



删除元素

删除元素不需要完全提供元素本身。只需要提供对排序有用的部分就行了。

他会查找和参数在排序上有并列关系的元素,即便这个元素和参数不是同一个东西。

Console.WriteLine(sortedSet.Count);
sortedSet.Remove(new Student() { id=12});
Console.WriteLine(sortedSet.Count);



确定是否包含元素

和删除元素一样,他不会检查参数和他储存的元素是不是真的是同一个。

只检查参数和自己元素中有没有并列关系的。

Console.WriteLine(sortedSet.Contains(new Student() { id = 12 }));



尝试获取元素

sortedSet.TryGetValue(new Student() { id = 11 }, out Student st);
Console.WriteLine(st.name);

同上,如果你知道他如何排序,只需要提供与排序有关的信息。

输出参数的值,是他里面的元素,包含着剩下部分的信息。

这个方法本身还会返回一个bool值,指示是否真的找到了有并列关系的元素。如果没找到,输出参数是默认值。



获得最值

有序集提供Min和Max两个属性,允许你获取当前的最小值和最大值。

但有序集不是时刻监视内部元素并排序的,如果你修改了他们的状态,可能导致整个排序都出现问题。

Console.WriteLine(sortedSet.Min.id);
sortedSet.Min.id = 999;
Console.WriteLine(sortedSet.Min.id);



有序列表

有序列表虽然说着列表,但是却和列表没什么关系。他更像字典,使用Key,Value对。

有序列表使用Key进行排序。每次添加或移除元素的时候都会对整个Key集合重新排序。

Value集合会跟随Key集合做参照排序。

Key类型必须是可排序的(实现IComparable泛型接口)

SortedList<string, int> sortedList = new SortedList<string, int>();



添加元素

sortedList.Add("null", 12);
sortedList["hello"] = 8; 

添加元素的操作和字典的操作一样,但是没有了TryAdd方法。



访问元素

和有序集一样,寻找Key值只检查有没有并列关系,不在乎是不是相同的。

Console.WriteLine(sortedList["hello"]);



删除指定Key与配对的Value

使用Remove方法,会移除和参数位置并列的Key,与其所对应的Value。



使用索引删除Key和Value

因为有序列表使用数组储存Key和Value,所以还是能找出他们的索引。

在找到索引之后,可以使用RemoveAt删除指定索引下的数据。

int index = sortedList.IndexOfKey("null");
sortedList.RemoveAt(index);

找索引这项工作也使用查找顺序并列完成。



有序字典

有序字典和有序列表几乎一样。

除了有序字典使用二叉搜索树而不是数组。

因此有序字典在插入和删除上比需要整理顺序的有序列表更快。

但是有序字典消耗更多的内存。

SortedDictionary<string, int> sortedDictionary = new SortedDictionary<string, int>();



版权声明:本文为zms9110750原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。