电话簿的数据结构
可能的重复:
存储 100 万个电话号码
如何设计包含 3 个电话地址簿的数据结构领域 姓名、电话号码、地址
必须能够在 3 个字段中的任何一个上搜索此电话簿
哈希表不起作用,因为所有三个字段都应哈希为相同的值,我认为这是不可能的。我也考虑过 trie 和其他数据结构,但想不出正确的答案。
Possible Duplicate:
storing 1 million phone numbers
How to design a data structure for a phone address book with 3 fields
name, phone number , address
one must be able to search this phone book on any of the 3 fields
Hash table wouldn't work because all the three fields should hash to the same value which is i think impossible. I thought about trie and other data structures too but couldn't think of a proper answer.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您应该使用
TRIE
数据结构来实现电话簿。TRIE
是一种使用字符串作为键的有序树数据结构。与二叉树
不同,TRIE
不存储与节点关联的键。很好的例子
You Should use
TRIE
data Structure for Implementing Phonebook.TRIE
is an ordered tree data structure that uses strings as keys. UnlikeBinary Trees
,TRIE
does not store keys associated with the node.Good example
您可以使用单个哈希表或其他类型的关联数组(如果您愿意)来完成此操作。对于每个人,表中只有三个键(姓名、地址、电话),全部指向同一条记录。
You could accomplish this with a single hash table or other type of associative array (if you wanted to). For each person, just have three keys in the table (name, address, phone) all pointing to the same record.
我认为 trie (每个电话簿条目都是一片叶子)和两个 跳过列表(每个姓名和地址一个)可能会很有效。
只需为每个节点分配一组指针以沿名称轴移动,并分配一组指针以沿地址轴移动(即遍历跳跃列表)。
I think a combination of a trie (each phone book entry is one leaf) and two skip lists (one for each name and address) could turn out to be effective.
Just assign each node one set of pointers to move along the name axis, and one set of pointers to move along the address axis (that is, to traverse the skip lists).
你不能同时用三种方式对某件事进行精确排序。您也不可能构建一个允许仅使用三分之一的键进行查找的哈希表。
您可能想要做的基本上就是数据库所做的事情:
因此,例如,您可以按照所需的顺序构建一个由 {name,phone,address} 结构组成的平面数组,然后对于每一行,将 (phone -> row#) 映射放入哈希表中。非唯一列可以散列到行号列表,或者您可以将它们放入二叉树中,其中重复键不成问题。
就空间要求而言,您基本上最终会将每个元素存储两次,因此您的空间要求至少会增加一倍。除此之外,您还获得了数据结构本身的开销;保持三个哈希表以约 70% 的容量加载,您的存储需求至少会增加 2.4 倍。
您可以通过保持主表在其中一列上排序来取消这些辅助查找结构之一,这样您就可以直接在 O(logN) 中搜索它。然而,这使得插入/删除行的成本非常昂贵(O(N)),但如果您的数据相当静态,那么这不是什么大问题。如果是这种情况,排序数组也将是辅助查找最节省空间的选择。
You can't exactly sort something in three ways at the same time. Nor can you feasibly build a single hash table which allows lookup with only a third of the key.
What you probably want to do is basically what databases do:
So, for example, you build a flat array of {name, phone, address} structs in whatever order you want, and then for each row, put a (phone -> row#) mapping into a hash table. Non-unique columns could hash to a list of row numbers, or you could put them in a binary tree where duplicate keys aren't an issue.
As far as space requirements, you basically end up storing every element twice, so your space requirement will at least double. On top of this you've got the overhead from the data structures themselves; keeping three hash tables loaded at ~70% capacity, your storage requirements increase by at least 2.4 times.
You can do away with one of these auxiliary lookup structures by keeping your main table sorted on one of the columns, so you can search on it directly in O(logN). However, this makes inserting/deleting rows very expensive (O(N)), but if your data is fairly static, this isn't much of an issue. And if this is the case, sorted arrays would be the most space-efficient choice for your auxiliary lookups as well.
在电话簿中,电话号码应该是唯一的,地址是唯一的,但姓名可以重复。
所以也许你可以使用哈希表和链表结合来解决这个问题。
您可以使用“姓名、地址、电话号码”中的任何一个或组合作为哈希键,如果您仅使用姓名作为哈希键,则需要链表来存储重复的条目。
在这种方法中,基于哈希键的搜索效率为 O(1),但基于其他两个的搜索效率为 O(n)。
in a phone book, the telephone number should be unique, address is unique, but the name could be duplicated.
so perhaps you can use hash table combine with linked list to approach this.
you can use any one or combination of the 'name, address, phone number' as hash key, if you simply use name as hash key, then linked list is needed to store the duplicated entries.
in this approach, search based on the hash key is O(1) efficiency, but search based on the other two will be O(n).
C、C++ 还是 C#?
使用课程列表
将其放入列表中,您就有了电话簿
C or C++ or C#?
Use a list of classes
place this in a list and you have a phone book
在 C 中,我认为结构体是最好的选择。
使用标准字符串函数(
或者如果使用 C++ 编译器,则
)或类似 glib 的函数用于搜索姓名、数字等。这是一个简单的示例:
还有一个很好的、有用的代码示例 此处。
或者,
您也许可以使用链表,但由于 C 或 C 标准库不提供链表,您要么需要自己实现,要么使用第三方库。
我建议使用
glib
中的g_linked_list
。In C, I think a struct is the best option.
Use the standard string functions (
<string.h>
or if using a C++ compiler,<cstring>
) or something like the glib for searching the names, numbers etc.Here's a simple example:
There is also a good, helpful code example over here.
Alternatively
You may be able to use linked lists, but since C or the C standard library doesn't provide linked-lists, you either need to implement it yourself, or to use a third-party library.
I suggest using the
g_linked_list
in theglib
.