C# 3.0 CookBook:三、类与结构(3):让类型支持搜索

本文介绍如何通过实现IComparable<T>和IComparer<T>接口,使自定义类型能够在List<T>和SortedList<K,V>中进行排序和二分搜索。通过示例演示了如何使用这些接口对Square对象进行排序,并在列表中进行高效查询。
摘要由CSDN通过智能技术生成

问题

    已有一个自定义类型可以像List<T>中的元素那样排序,还要使用BinarySearch方法在该列表对其自定义的类型制定查询规则。

解决方案

    使用IComparable<T> 和IComparer<T>接口。使用3-1节中的Square类,以List<T>和SortedList<K,V>集合对Square对象实现排序和查询的方法实现IComparable<T>接口。

讨论

    依靠在用户自定义的类(或结构)中实现IComparable<T>接口,可以得到List<T>和SortedList<K,V>类中一样的搜索算法的优势。在这些类中的内置搜索算法中,用户只需要实现IComparable<T>接口告诉这些类要怎样查找用户自定义类型。

    关于实现CompareTo方法,可参见3-2节

    List<T>类提供了BinarySearch(二分搜索)方法来对列表中的元素进行搜索。每一个元素都会和另一个作为参数传入BinarySearch方法中的元素对象进行比较。SortedList类型没有包含BinarySearch方法,而是用ContainsKey方法进行代替,该方法对列表中包含的键值进行二分搜索。SortedList类中ContainsValue方法则是使用线性搜索法搜索列表中的值。该方法则是调用SortedList集合中的Equals方法来完成搜索。SortedList类中的线性搜索算法在使用Compare和CompareTo方法时没有任何的优越效果,但是它们在二分搜索上使用很有效。

要使List<T>类型使用BinarySearch方法得到准确的搜索结果,要先调用List<T>方法的Sort方法。此外,如果在BinarySearch方法中使用IComparer<T>接口,必须对Sort方法传递一个一样的接口。否则,BinarySearch方法可能将无法找到目标对象。

    示例3-4中的TestSort方法示范了怎样在List<Square>和SortedList<int,Square>集合的实例中使用Square类和CompareHeight类。

//示例3-4.让类型支持搜索
public static void TestSearch()
{
    List<Square> listOfSquares = new List<Square> {new Square(1,3),
                                                   new Square(4,3),
                                                   new Square(2,1),
                                                   new Square(6,1)};
    IComparer<Square> heightCompare = new CompareHeight();
    // Test a List<Square>
    Console.WriteLine("List<Square>");
    Console.WriteLine("Original list");
    foreach (Square square in listOfSquares)
    {
        Console.WriteLine(square.ToString());
    }
    Console.WriteLine();
    Console.WriteLine("Sorted list using IComparer<Square>=heightCompare");
    listOfSquares.Sort(heightCompare);
    foreach (Square square in listOfSquares)
    {
        Console.WriteLine(square.ToString());
    }
    Console.WriteLine();
    Console.WriteLine("Search using IComparer<Square>=heightCompare");
    int found = listOfSquares.BinarySearch(new Square(1, 3), heightCompare);
    Console.WriteLine("Found (1,3): " + found);
    Console.WriteLine();
    Console.WriteLine("Sorted list using IComparable<Square>");
    listOfSquares.Sort();
    foreach (Square square in listOfSquares)
    {
        Console.WriteLine(square.ToString());
    }
    Console.WriteLine("Search using IComparable<Square>");
    found = listOfSquares.BinarySearch(new Square(6, 1)); // Use IComparable
    Console.WriteLine("Found (6,1): " + found);
    // Test a SortedList<Square>
    var sortedListOfSquares = new SortedList<int, Square>(){
                                        {0, new Square(1,3)},
                                        {2, new Square(4,3)},
                                        {1, new Square(2,1)},
                                        {4, new Square(6,1)}};
    Console.WriteLine();
    Console.WriteLine();
    Console.WriteLine("SortedList<Square>");
    foreach (KeyValuePair<int, Square> kvp in sortedListOfSquares)
    {
        Console.WriteLine(kvp.Key + " : " + kvp.Value);
    }
    Console.WriteLine();
    bool foundItem = sortedListOfSquares.ContainsKey(2);
    Console.WriteLine("sortedListOfSquares.ContainsKey(2): " + foundItem);
    // Does not use IComparer or IComparable
    // -- uses a linear search along with the Equals method
    // which has not been overloaded
    Square value = new Square(6, 1);
    foundItem = sortedListOfSquares.ContainsValue(value);
    Console.WriteLine("sortedListOfSquares.ContainsValue(new Square(6,1)): " + foundItem);
}

    上述代码输出结果如下所示:

List<Square>
Original list
Height:1 Width:3
Height:4 Width:3
Height:2 Width:1
Height:6 Width:1
Sorted list using IComparer<Square>=heightCompare
Height:1 Width:3
Height:2 Width:1
Height:4 Width:3
Height:6 Width:1
Search using IComparer<Square>=heightCompare
Found (1,3): 0
Sorted list using IComparable<Square>
Height:2 Width:1
Height:1 Width:3
Height:6 Width:1
Height:4 Width:3
Search using IComparable<Square>
Found (6,1): 2
SortedList<Square>
0 : Height:1 Width:3
1 : Height:2 Width:1
2 : Height:4 Width:3
4 : Height:6 Width:1
sortedListOfSquares.ContainsKey(2): True
sortedListOfSquares.ContainsValue(new Square(6,1)): True

还可参见

    3-2节;MSDN文档中“IComparable<T>接口”主题和“IComparer<T>接口”主题。

版权说明:作者:张颖希PocketZ's Blog
出处:http://www.cnblogs.com/PocketZ
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

本文翻译内容取自网络,纯粹是练习英文水平,如有雷同,纯属意外!有不妥之处,欢迎拍砖!

转载于:https://www.cnblogs.com/PocketZ/archive/2010/04/26/Making_a_Type_Searchable.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值