电话簿的数据结构

发布于 2025-01-01 18:29:33 字数 322 浏览 0 评论 0原文

可能的重复:
存储 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

深居我梦 2025-01-08 18:29:33

您应该使用 TRIE 数据结构来实现电话簿。 TRIE 是一种使用字符串作为键的有序树数据结构。与二叉树不同,TRIE不存储与节点关联的键。

很好的例子

You Should use TRIE data Structure for Implementing Phonebook. TRIE is an ordered tree data structure that uses strings as keys. Unlike Binary Trees, TRIE does not store keys associated with the node.

Good example

从此见与不见 2025-01-08 18:29:33

您可以使用单个哈希表或其他类型的关联数组(如果您愿意)来完成此操作。对于每个人,表中只有三个键(姓名、地址、电话),全部指向同一条记录。

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.

半﹌身腐败 2025-01-08 18:29:33

我认为 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).

深海蓝天 2025-01-08 18:29:33

你不能同时用三种方式对某件事进行精确排序。您也不可能构建一个允许仅使用三分之一的键进行查找的哈希表。

您可能想要做的基本上就是数据库所做的事情:

  • 存储所有记录的一个(可能未排序的)主列表。
  • 对于您希望能够搜索的每一列,构建某种查找结构,该结构将指针/索引返回到主列表中。

因此,例如,您可以按照所需的顺序构建一个由 {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:

  • Store one (possibly unsorted) master list of all your records.
  • For each column you want to be able to search on, build some kind of lookup structure which returns a pointer/index into the master list.

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.

黯然 2025-01-08 18:29:33

在电话簿中,电话号码应该是唯一的,地址是唯一的,但姓名可以重复。

所以也许你可以使用哈希表和链表结合来解决这个问题。

您可以使用“姓名、地址、电话号码”中的任何一个或组合作为哈希键,如果您仅使用姓名作为哈希键,则需要链表来存储重复的条目。

在这种方法中,基于哈希键的搜索效率为 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).

記柔刀 2025-01-08 18:29:33

C、C++ 还是 C#?

使用课程列表

    public class PhoneBook
{
    public string name;
    public string phoneNumber;
    public string address;
}

将其放入列表中,您就有了电话簿

C or C++ or C#?

Use a list of classes

    public class PhoneBook
{
    public string name;
    public string phoneNumber;
    public string address;
}

place this in a list and you have a phone book

此刻的回忆 2025-01-08 18:29:33

在 C 中,我认为结构体是最好的选择。

typedef struct _Contact Contact;

struct _Contact
{
    char* name;
    char* number;
    char* address;
};

Contact* add_new_contact( char* name, char* number, char* address )
{
    Contact* c = (Contact*) malloc( sizeof( Contact ) );
    c->name = name;
    c->number = number;
    c->address = address;
    return c;
}

Contact* phone_book [ 20 ];  /* An array of Contacts */

使用标准字符串函数( 或者如果使用 C++ 编译器,则 )或类似 glib 的函数用于搜索姓名、数字等。

这是一个简单的示例:

Contact* search_for_number( Contact* phone_book[], const char* number )
{
    register int i;
    for( i = 0; i < sizeof( phone_book ); i++)
    {
       if ( strcmp( phone_book[i]->number, number ) == 0 ) return phone_book[i];
    }
    return NULL;
}

还有一个很好的、有用的代码示例 此处

或者,

您也许可以使用链表,但由于 C 或 C 标准库不提供链表,您要么需要自己实现,要么使用第三方库。

我建议使用glib中的g_linked_list

In C, I think a struct is the best option.

typedef struct _Contact Contact;

struct _Contact
{
    char* name;
    char* number;
    char* address;
};

Contact* add_new_contact( char* name, char* number, char* address )
{
    Contact* c = (Contact*) malloc( sizeof( Contact ) );
    c->name = name;
    c->number = number;
    c->address = address;
    return c;
}

Contact* phone_book [ 20 ];  /* An array of Contacts */

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:

Contact* search_for_number( Contact* phone_book[], const char* number )
{
    register int i;
    for( i = 0; i < sizeof( phone_book ); i++)
    {
       if ( strcmp( phone_book[i]->number, number ) == 0 ) return phone_book[i];
    }
    return NULL;
}

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 the glib.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文