Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 任何复杂度为0(1)或O(Logn)的.net集合,用于查找和删除、添加和插入_C#_.net_Generics_Collections_Observablecollection - Fatal编程技术网

C# 任何复杂度为0(1)或O(Logn)的.net集合,用于查找和删除、添加和插入

C# 任何复杂度为0(1)或O(Logn)的.net集合,用于查找和删除、添加和插入,c#,.net,generics,collections,observablecollection,C#,.net,Generics,Collections,Observablecollection,我遇到了一个非常奇怪的情况,我创建了一个类ObservableList,如下所示 class observableList<T>:IObservableList<T>, IList, IUserCollectionType { private List<T> _list; private HashSet<T> _containedElements // for each operation add,insert,remove I k

我遇到了一个非常奇怪的情况,我创建了一个类ObservableList,如下所示

class observableList<T>:IObservableList<T>, IList, IUserCollectionType 
{

  private List<T> _list;

  private HashSet<T> _containedElements

// for each operation add,insert,remove I keep HashSet and List in synch.
}
class observableList:IObservableList、IList、IUserCollectionType
{
私人名单(private List);;
私有HashSet_包含元素
//对于每个操作add、insert、remove,我都保持HashSet和List的同步。
}
}

我需要HashSet进行快速查找,但HashSet不是有序集合,我需要list,因为我需要引发CollectionChanged事件,但它需要项的索引。所以,为了排序,我必须使用列表,为了快速查找,我必须使用哈希集

但现在,我遇到了一个问题,从列表中删除需要O(n)。首先我必须获取索引,然后使用removeAt()方法,我必须获取索引,因为我必须引发集合更改事件

现在,我正在寻找一个解决方案,其查找的复杂性为O(1)或O(Logn),删除也有顺序。 我不能使用dicitonary,因为如果我将索引作为键,并删除任何项,那么我必须将项的键更新1

**那么,为什么我们没有复杂度为O(1)或接近O(1)的集合呢

1。用于查找
2.要删除,请添加并插入。
3.应订购集合

在Java中,有人告诉我可能有一个类Linkedhashmap,但我对此不确定。那么,对于这个集合,.NET是否有替代方案


或者我们有没有这样的开源库。

您可以通过使用.Net的
LinkedList
Dictionary
类构建类似于Java的
LinkedHashSet
的东西来获得所需的性能。这可以为您提供O(1)查找、插入和删除,以及保留插入顺序

我在下面画出这个解决方案;请注意,这样就省去了一些问题,例如检查重复的元素,或者实际实现IObservableList部分以及您可能需要的一些其他方法。还要注意,这基本上是伪代码,我没有编译或测试它

class LinkedHashSet<T>
{
    private LinkedList<T> _list;
    private Dictionary<T, LinkedListNode<T>> _containedElements

    public void Add(T value)
    {
        LinkedListNode<T> newNode = _list.AddLast(value);
        _containedElements[value] = newNode;
    }

    public void Remove(T value)
    {
        LinkedListNode<T> node = _containedElements[value];
        _containedElements.Remove(value);
        _list.Remove(node);
    }

    public bool Contains(T value)
    {
        return _containedElements.ContainsKey(value);
    }
}
类LinkedHashSet
{
私有链接列表;
专用词典(包含元素)
公共无效添加(T值)
{
LinkedListNode newNode=\u list.AddLast(值);
_containedElements[值]=新节点;
}
公共无效删除(T值)
{
LinkedListNode节点=_包含元素[值];
_包含元素。删除(值);
_列表。删除(节点);
}
公共布尔包含(T值)
{
返回_containedElements.ContainsKey(值);
}
}
编辑:解决整个问题

正如我在评论中已经说过的那样,我注意到上述内容并不是问题的完整解决方案,因为问题还涉及到一个附加操作:在列表中查找给定项的索引(至少在删除的上下文中)

我还没有完全解决这个问题的方案,但我有一个可能可行的想法,所以这里让这个答案更完整一点:

您可以用平衡的二叉树结构(例如红黑树)替换上例中的
LinkedList
。此树中的每个节点都引用一个值(就像链表中的每个节点一样),并且每个节点还将其子节点的计数存储在树中

您可以通过从根开始递减并在左侧最多保留
i
节点,在O(log(n))时间内通过其索引
i
找到任何元素。由于每个节点都会告诉您其子节点的数量,因此您只需查看遇到的每个节点的左子节点,就可以确定是否需要继续向左或向右(或者当前节点是否包含目标节点)

插入或删除元素通常在红黑树中完成,但需要更新所有受影响节点及其祖先中的后代和计数。我并没有完全解决这一部分,但我很确定这在O(log(n))时间内仍然是可能的,就像在“正常”的红黑树中一样

最后,您可以在O(log(n))时间内找到任何元素的索引,方法是从其节点开始,沿着树向上走,计算左侧的所有节点(再次使用每个节点中的degender和count)。在上面的示例中,节点本身将被字典引用,因此您实际上可以高效地找到它


总之,将上述示例中的
LinkedList
替换为此处描述的树数据结构将为您提供O(log(n))插入、删除、按值索引查找和按索引值查找、O(1)遍历(摊销)和O(1)包含检查,所有这些都假设字典操作与O(1)一起工作.

我想您可以使用SortedList。不幸的是,从分类列表中删除是O(N)我认为实际上不可能有一个O(1)复杂度的有序集合进行插入或删除。@MatthewWatson,我也知道这一点,但是否有任何解决方法或任何东西……Alex,它不需要只有O(1)小于O(N)列表的所有内容。删除()是O(n)。它调用IndexOf(object),然后调用RemoveAt(index);Remove()有两个重载,我使用的是一个接受LinkedListNode的重载:你是对的。我将留下我的评论,因为你的回答对其他人很有用。