【发布时间】:2011-03-19 21:23:25
【问题描述】:
我在一次采访中被问到这个问题。
是否存在具有以下两种能力的数据结构:
1。恒定时间访问(Random Access),如ArrayList
2。可变大小,如 LinkedList
如果没有这样的数据结构,自己创建一个。
【问题讨论】:
-
呃,ArrayList 是可变大小(?)
标签: java data-structures
我在一次采访中被问到这个问题。
是否存在具有以下两种能力的数据结构:
1。恒定时间访问(Random Access),如ArrayList
2。可变大小,如 LinkedList
如果没有这样的数据结构,自己创建一个。
【问题讨论】:
标签: java data-structures
我相信您正在寻找的答案是“哈希表”(See: "Hash Table" in Wikipedia),因为您评论说他们正在寻找 ArrayList 之外的另一个答案(对于 Java,请参阅:Hashtable)
但请注意,它可能接近恒定时间,具体取决于散列算法和数据集,因为可能会发生冲突,从而导致(短)二次线性搜索。 Javadoc 很好地解释了在 Java 实现中是如何处理的。
【讨论】:
除了Brian Roach所说的HashTable之外,面试官可能一直在暗指LinkedHashMap或LinkedHashSet,它为一些基本操作提供了大约恒定的时间性能,同时还保持插入顺序,因为它将 HashTable 与双向链表相结合。
换句话说,您将元素放入 LinkedHashMap 的顺序将与您在键上循环时检索它们的顺序相同。
使用 Sets 的一个缺点是您不能有重复项,而且 Maps 也不能有重复的键。解决方法是使用一组列表,或使用 Google 的 Multimap 之类的东西。
但正如其他人所说,ArrayList 已经满足了这两个要求。这是一个没有可变大小的数组。
另外,与 ArrayList 的 O(n) 性能相比,LinkedList 相对于 ArrayList 的主要优势是 constant time insertion/deletion 在列表的末尾和开头。两者都可以提供可变大小。
【讨论】:
deque 或“双端队列”怎么样?在许多实现中,除了 head 或 tail 之外,它不会有效地改变任何位置的插入和删除大小,但它提供了您寻求的两个属性:
您在问题中提到了 Java(通过标记),我必须注意 Java 中的 the Deque interface 确实不提供随机访问。甚至the ArrayDeque concrete class 也不提供。这是一个不幸的选择,是为了更抽象和对接口施加尽可能少的要求。
无论如何,在 Java 之外,您会发现确实满足您要求的属性的双端队列实现。
【讨论】:
为什么没有一个哈希表并在其中插入所有元素,同时在LinkedList中插入元素并在恒定时间内从哈希表中读取。
【讨论】: