是否存在IList <t>的实现,其中Contains(T)是O(1)操作?</t>

时间:2009-09-18 08:17:49

标签: c# collections

我想知道是否有一个IList<T>实现由HashSet<T>之类的哈希支持但提供索引访问?

要清楚,我并不关心如何实施,只是想知道是否有人知道它是否已经可用。

7 个答案:

答案 0 :(得分:3)

您可以自己实施IList<T>并保留两个支持集合 - List<T> a HashSet<T>。基本上让Visual Studio为IList<T>中的所有内容提供“抛出异常”实现,然后为每个方法确定是否要将其代理到列表或集合。

当然你必须小心重复等等(定义{{​​1}},Add(x)Add(x)Remove(x)的行为 - 你最终可能会遇到它在列表中,但不是集合)但它不会太难。

答案 1 :(得分:1)

在.NET 4中有一个新的SortedSet<T>类,其中Contains()为O(1),请参阅this MSDN page

答案 2 :(得分:1)

快速回答 - 不,它还没有。

当您意识到时,实施它当然很容易。它不常用的原因如下。如果你可以在O(1)中包含,那么你可以在O(1)中进行索引查找。但是,如果您有重复的元素,索引查找当然不是唯一的。

你基本上需要的是两个数据结构,一个Set(或Map)和一个List,并没有比这更有效的方法,标准库作者让你结合数据 - 构建自己。

答案 3 :(得分:0)

KeyedCollection<TKey, TItem>提供了这种类型的功能,但您必须从中派生并为其提供从散列的项中提取密钥的功能。

答案 4 :(得分:0)

您可以将任意数量的(散列或其他)索引放入双向链接列表节点(双重链接,以便删除O(1))。

答案 5 :(得分:0)

.Net 3.5中没有,但它很容易实现:

public class Set<T> : KeyedCollection<T,T>
{
    public Set()
    {}

    public Set(IEnumerable<T> collection)
    {
        foreach (T elem in collection)
        {
            Add(elem);
        }
    }

    protected override T GetKeyForItem(T item)
    {
        return item;
    }
}

答案 6 :(得分:0)

HashSet<T>实现ICollection<T>,如果有用的话。从3.5开始提供。