哪个数据结构用于实现可以在姓名或电话号码上搜索的电话簿?

时间:2017-10-24 08:09:58

标签: algorithm data-structures

pl建议一个适当的数据结构来实现一个电话词典,它只有人名和电话号码。我可以想到使用名称作为键和电话号码作为值的哈希表。

但问题是,鉴于他的电话号码,我们无法搜索姓名。 可以假设所有名称都是唯一的。

~Ashish

4 个答案:

答案 0 :(得分:1)

由一对尝试组成的数据结构可能效果很好。一个trie会给你一个给出姓名的电话号码,另一个会给你一个给出电话号码的名字。

树的节点为您提供名称的电话号码,其边缘标有构成名称的符号。与每个顶点相关联的值将是指向另一个trie(给出电话号码名称的节点)中的节点的指针,该节点对应于名称从根到顶点的人的电话号码。根据名称,您可以返回具有该名称的人的相应电话号码(通过从链接节点遍历到根目录)。实际上,您可以使用它来查找名称以特定前缀及其相应电话号码开头的所有人。

以下是名称到电话号码trie的示例:

  J    A    C    K
1--->2--->3--->4--->5
     |    |
   I |  S V 
     |    9--->10--->11
     V      O     N
     6--->7--->8
       L    L

假设代表的人是Jack,Jill,Jason和Jaso(外国留学生)。另一个特里可能看起来像这样:

  1    2    3
A--->B--->C--->D
     |    |
   3 |    V 2
     |    E
     V 3
     F--->G
     |
   2 |
     V
     H

电话号码是123,122,133和132.

现在,引用将如下所示:

Name Trie    Number Trie
---------    -----------
1->null      A->null
2->null      B->null
3->null      C->null
4->null      D->10
5->E         E->5
6->null      F->null
7->null      G->8
8->G         H->11
9->null
10->D
11->H

输入JAS到名称trie后,我们可以轻松确定此名称没有数字,因为节点9没有相应的数字。假设我们想列出所有姓名开始的人的所有号码。我们可以使用您喜欢的任何方法遍历树(基于字母顺序的顺序遍历似乎是理智的),我们看到JASO (10)JASON (11)在电话号码中有相应的节点。

对于这些节点中的每一个,我们都可以跳转到电话号码trie并返回到父节点(假设我们在每个节点中保存了父引用,这是可行的)。在此过程中,我们可以跟踪边缘标签以获得与我们的节点对应的数字。自10->D起,我们在返回根C的路上找到BAA,并且沿途的数字为321。通过以回溯期间看到的顺序连接它们,然后反转该连接,我们获得从AD的字符串,因此对应于JASO的字符串:{{1} }。同样适用于123

添加新条目意味着同时向两个尝试添加条目,然后链接它们。如果允许重复的名称或数字,则可以引用节点集合,而不是指向另一个节点中的一个节点。删除条目意味着只需从每个树中删除相应的节点。有效名称是带有电话号码的名称。有效的电话号码是引用名称的电话号码。

答案 1 :(得分:0)

如果您希望快速查看名称,可以实现尝试。

尝试基本上是树,其中每个节点连接到n个子节点,其中n是您可以想到的字符数(对于搜索字符串中的小字符可以是26,如果您不同地考虑大写和小写字母,则为52) 62如果你也将数字带入索引中,所有这些都基于你对Trie的要求。

可以找到更多信息here

可以找到trie的示例实现here

可以有效地使用Tries进行部分字符串搜索。

搜索和插入的复杂性仅限于被搜索词的长度O(length)

答案 2 :(得分:0)

使用Gauva Bimap并反转它。

BiMap<Integer, String> biMap = HashBiMap.create(); biMap.put(9856435634, "M"); biMap.put(9856435635, "S"); biMap.put(9856435636, "R");  System.out.println(biMap.inverse().get("M")); 

答案 3 :(得分:0)

选择数据结构取决于可用资源,即时间和空间(处理器和内存),在我们的时间内,具有高规格的硬件是主要的,因此如果您针对良好的规格,我建议您通过实施链表,每个节点包含名称和编号,然后实现两个函数,一个用于使用名称进行搜索,另一个用于编号,还可以对名称进行排序,以便在搜索名称时使用二进制搜索。

请注意,链接列表的Worst caseAccess的{​​{1}}时间为Search,空间为O(n),这对于良好的规范来说相当不错硬件,有关常见数据结构的时间和空间复杂性的更多详细信息,请参阅此Link,以便根据您的要求进行比较和选择合适的数据。