电话簿的数据结构

时间:2012-02-02 05:08:59

标签: algorithm data-structures

  

可能重复:
  storing 1 million phone numbers

如何为包含3个字段的电话通讯簿设计数据结构 姓名,电话号码,地址

必须能够在3个字段中的任何一个字段中搜索此电话簿

哈希表不起作用,因为所有三个字段都应该哈希到相同的值,这是我认为不可能的。我也考虑过trie和其他数据结构,但却没有想到正确的答案。

7 个答案:

答案 0 :(得分:6)

您应该使用TRIE数据结构来实施电话簿。 TRIE是一个使用字符串作为键的有序树数据结构。与Binary Trees不同,TRIE不存储与节点关联的密钥。

Good example

答案 1 :(得分:5)

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

答案 2 :(得分:3)

我认为trie(每个电话簿条目是一个叶子)和两个skip lists(每个名称和地址一个)的组合可能会变得有效。

只需为每个节点分配一组指针以沿着名称轴移动,并为一组指针分配沿地址轴移动(即遍历跳过列表)。

答案 3 :(得分:1)

您不能同时以三种方式对事物进行精确排序。你也不可能建立一个单独的哈希表,只允许用密钥的三分之一进行查找。

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

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

因此,例如,您可以按照您想要的顺序构建{name,phone,address}结构的平面数组,然后对于每一行,将(phone - > row#)映射放入哈希表中。非唯一列可以散列到行号列表,也可以将它们放在二叉树中,其中重复键不是问题。

就空间要求而言,基本上最终会将每个元素存储两次,因此您的空间要求至少会增加一倍。除此之外,您还可以从数据结构本身获得开销;保持三个哈希表的容量为~70%,您的存储需求至少增加2.4倍。

您可以通过保持主表在其中一列上排序来取消其中一个辅助查找结构,因此您可以直接在O(logN)中搜索它。但是,这会使插入/删除行非常昂贵(O(N)),但如果您的数据相当静态,那么这不是什么大问题。如果是这种情况,排序数组也是辅助查找的最节省空间的选择。

答案 4 :(得分:0)

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

所以也许您可以使用散列表与链接列表结合来实现此目的。

您可以使用姓名,地址,电话号码中的任意一个或组合。作为哈希键,如果您只是使用名称作为哈希键,则需要链接列表来存储重复的条目。

在这种方法中,基于散列键的搜索效率是O(1),但基于其他两种搜索将是O(n)。

答案 5 :(得分:-1)

C或C ++或C#?

使用班级列表

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

将其放在一个列表中,你有一本电话簿

答案 6 :(得分:-1)

在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 */

使用标准字符串函数(<string.h>或使用C ++编译器,<cstring>)或类似 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;
}

here还有一个很好的,有用的代码示例。

替代地

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

我建议使用g_linked_list中的glib

相关问题