我最近在接受采访时被问到advantages and disadvantages of linked list and arrays for dictionary of words implementation
以及what is the best data structure for implementing it?
这是我把事搞砸的地方。谷歌搜索后,我无法专门找到特定于词典的确切答案,但一般链表v阵列解释。 上述问题的最佳答案是什么?
答案 0 :(得分:1)
好吧,如果您正在构建字典,那么您希望它是一个排序结构。所以你要去排序数组或排序链表。
O(n)
,因为您必须检查所有单词,直到找到所需的单词。对于已排序的数组,您可以使用二进制搜索来查找正确的位置,即O(log n)
。 O(log n)
以找到正确的位置(二进制搜索),然后插入O(n)
,因为您需要将所有内容都向下推。对于链接列表,找到位置然后O(n)
将被O(1)
插入,因为您只需要调整指针。这同样适用于删除。由于您不会更新字典,您可以在O(nlog n)
时间内构建然后对数组进行排序(例如使用quicksort)。之后,使用二进制搜索查找O(log n)
。此外,正如下面提到的delnan,使用数组的优点是您访问的所有内容都是连续的内存;即,数据被定位(参考的位置)。这最大限度地减少了缓存未命中(这是很昂贵的)。使用链表,数据遍布全部,并且无法保证它们靠近在一起,这增加了缓存未命中的可能性。考虑到这两个选项,请使用数组。
如果使用红黑树实现已排序的hashmap(您的树条目,其中的键可以与hashmap结合),您可以做得更好;这里的搜索,插入和删除都是O(log n)
。但这实际上取决于你的行为特征;如果您只进行查找,则最好使用简单的散列图(O(1)
检索)。
您可以使用的另一个有趣的数据结构是Trie,其中插入和查找是O(m)
; m
是字符串的长度。
答案 1 :(得分:1)
如果您只是将其用于查找,那么数组就是两者中最明显的选择。您可以从O(n log n)中的单词列表构建字典 - 只需构建一个数组并对其进行排序。查找是O(log n),带有二分搜索。
虽然您可以在O(n)中构建单词的链接列表,但查找平均需要查看n / 2个单词。差异非常大。给定128K字的英语字典,链表查找平均需要64,000个字符串比较。二进制搜索最多需要 17。
此外,n个单词的链接列表将占用比n个单词数组更多的内存,因为您需要列表中的next
指针。
如果您需要更新字典的能力,如果与查找相比更新很少,那么您可能仍然希望使用数组(几乎可以肯定是这种情况)。我无法想到一个真实世界的单词词典示例,这些词典的更新频率高于它的查询。
正如其他人所指出的那样,数组和链表都不是单词词典的最佳选择。但是在你给出的两个选项中,阵列在几乎所有情况下都是优越的。
答案 2 :(得分:0)
没有一个答案。
如果您只想查找单个项目,或者如果您想查找项目范围,则基于平衡树的内容可以选择基于哈希表的两个明显选择。
如果您进行大量搜索并且插入或删除相对较少,则排序数组可以正常工作。找到首选链表的情况要困难得多。根据情况(特别是找到所有开头的单词,例如" ste"),尝试也可以非常好地工作(并且通常可以最大限度地减少给定集合所需的存储空间)数据也是如此。
这些是非常广泛的类别,而不是具体的实现。还有一些变体,例如可扩展散列和分布式散列表,它们在特定情况下很有用(并且还具有类似树状的属性,因此基于范围的搜索等方法可以合理有效)。
答案 3 :(得分:0)
实施字典的最佳数据结构是suffix trees
。您还可以查看tries
。