【发布时间】:2012-11-17 21:32:45
【问题描述】:
我的目标是创建一个实现IList<T> 接口的数据结构,它将通过牺牲内存来实现O(1) 元素查找时间。
背景
如您所知,所有基于数组的IList<T> 实现(如List<T>)都有O(n) 元素查找时间。这意味着像 int IndexOf(T element) 或 bool Contains(T element) 这样的操作会遍历底层数组,直到找到匹配项。
众所周知的想法是使用列表和哈希表的组合作为底层数据结构。值保存在列表中。哈希表将索引作为值和列表的值作为键。因此可以使用哈希表进行查找。
这正是KeyedCollection<TKey, TItem> see MSDN 的实现方式。
到目前为止我已经尝试过什么
internal class MyList<T> : KeyedCollection<T, T>
{
protected override T GetKeyForItem(T item)
{
return item;
}
}
到目前为止,除了一个问题外,这一直有效。这个数据结构并没有完全模仿List<T> 背后的预期行为。关键是List<T> 允许重复,MyList 不允许。
问题
有没有现成的数据结构,或者你能推荐一种优雅的方式来实现IList<T>,以便:
- 查找操作的时间为
O(1)。 - 所有其他操作具有与
O()相同的性能List<T> - 内存可能会受到哈希表开销(
constantA + constantB * n字节)的影响。 - 必须允许重复
- 允许空值是可选的(可以将它们装箱到空对象中)
【问题讨论】:
-
“必须允许重复”是什么意思。是否需要保留重复的每个实例,忽略重复,覆盖重复?
-
我认为其中最棘手的部分将匹配
IndexOf的定义,该定义声明:“如果一个对象在列表中多次出现,IndexOf 方法总是返回找到的第一个实例。” -
您不断将您的数据结构与
List和Set同时进行比较。两者之间不仅性能不同,而且 API 也有很大差异。集合是无序的,列表是有序的,这产生了很大的不同。你的收藏会被订购吗?拥有一个允许重复的集合/映射称为“包”(仍然是无序的)。不存在具有 O(1) 搜索速度的列表。 -
@achitaka-san 那么这是不可能的。完成。
-
最好的情况是你嫁给
Dictionary<T,LinkedList<T>>和List<LinkedListNode<T>>。处理dictMapListHashStructKerfloovy[17] = newValue;之类的事情太可怕了。
标签: c# .net performance data-structures collections