这两种情况下C的最佳数据结构是什么?

时间:2009-03-22 04:02:52

标签: c data-structures tree hashtable hashmap

我有点需要做出决定,看看我能否在我的学校项目截止日期前几个小时内完成,但我对数据结构了解不多,我需要建议......

我需要做两件事,他们可能会使用不同的数据结构。

  1. 我需要一个数据结构来保存个人资料记录。必须按名称和社会安全号码搜索个人资料。 SSN是独一无二的,所以我可能会利用它来获得优势吗?我想哈希地图是最好的选择吗?但是,如何在哈希映射中使用SSN将其用作查找特定配置文件的优势?我们非常感谢您提供基本且易于理解的解释。

  2. 我需要一个数据结构来保存有关城市的记录。 我需要知道访问量最多的城市,访问量较少的城市以及客户(有关客户数据的#1数据结构中的个人资料)访问特定城市

  3. 这是我项目所需的第三个数据结构,而且我不知道从哪里开始的数据结构。如果可能的话,建议使用哪种类型的数据结构,并举例说明如何以粗体显示上述数据。

    作为备注:
    第一个数据结构已经完成(我在a previous question中谈过它)。第二个是在#1上发布的,虽然其他小组成员正在处理,我只需要知道我们要做的是“最佳”方法。第三个是#2,我最需要帮助的那个。

3 个答案:

答案 0 :(得分:3)

答案位于平衡搜索树和数组之间的任何位置。

你在这里提到的情况和其他线程错过了非常重要的一点:你正在处理的数据的大小。您可以根据必须处理的数据量选择数据结构和算法。重要的是,您能够证明您的选择是正确的。使用效率较低的通用算法并不总是。能够备份你的选择(例如:选择冒泡排序,因为数据大小<10,总是)显示a)更强的领域命令和b)实用主义 - 两者都供不应求。

答案 1 :(得分:1)

对于跨多个键的可搜索性,以任何方便的形式存储数据,并为键提供快速查找索引。

这可能就像按照创建顺序将数据保存在数组(或链接列表或...)中一样简单,并保留一堆{hashtables | sorted arrays | btree}的地图{{1}对于所有有趣的键(SSN,名称,......)。

如果您有更多时间,您甚至可以了解如何为每个不同的地图设置不同的(key, data*) ...

我认为这个解决方案可能适用于您的两个问题。

祝你好运。


为清楚起见:

首先,我们有一个简单的学生记录数组

struct

随时随地填写。它没有顺序,因此在任何键上搜索是线性时间操作。对于1,000个条目来说不是问题,但对于10,000个问题可能是一个问题,当然也有100万个问题。请参阅dirkgently's comments

如果我们想要快速搜索,我们需要另一层结构。我在密钥和主数据结构之间构建了一个映射,如下所示:

typedef
struct student_s {
   char ssn[10]; // nul terminated so we can use str* functions 
   char name[100];
   float GPA;
   ...
} student;
student slist[MAX_STUDENTS];

并在密钥上维护skey 排序,以便我可以快速查找。 (只有一个数组是保持排序的麻烦,所以我们可能更喜欢树或散列图。)

如果您只想在单个字段上进行快速搜索,则不需要(并且当然应该避免)这种复杂性。

答案 2 :(得分:1)

在作业问题之外,您将使用关系数据库 这个。但这可能对你没有帮助......

你需要弄清楚的第一件事,正如其他人已经指出的那样 out,你正在处理多少数据。 O( n )强力搜索是 只要 n 很小,就会很快。由于数据量很小 使这成为一个微不足道的问题(把它放在一个数组中,只是蛮力 搜索它),我将假设数据量很大。

存储城市

首先,您的搜索要求似乎需要排序的数据 多种方式:

  1. 某个城市唯一标识符(名称?)
  2. 访客人数
  3. 这实际上并不难以满足。 (1)最简单。存放 一些阵列中的城市。数组索引成为唯一标识符 (假设:我们不会删除城市,或者如果我们删除城市,我们可以 只是让那个阵列点不用,浪费一些内存。添加就可以了。)

    现在,我们还需要能够找到最多的&amp;访问次数最少。假设 可能会发生修改(例如,添加城市,更改数量) 访问者等)并从关系数据库借用,我建议 使用某种形式的平衡树创建索引。数据库会 通常使用B树,但不同的可能对你有用:检查维基百科 树上的文章。在每个树节点中,我只保留一个指针(或 数据索引)城市数据。没理由再复制一份!

    我推荐一个哈希树,原因很简单:你可以 轻松做预订或逆序遍历找到顶部或 底部N个项目。哈希不能这样做。

    当然,如果修改可能不会发生,只需使用另一个数组( 指向项目的指针,再一次,不要复制它们。)

    将城市链接到个人资料

    如何执行此操作取决于您如何查询数据以及使用何种形式 它可以采取。最通用的是每个配置文件可以关联 与多个城市和每个城市可以关联多个 配置文件。此外,我们希望能够从两者中有效地进行查询 方向 - 问两个“谁来凤凰?”和“鲍勃哪些城市 访问?”。

    再次从数据库中无耻地解除,我会创建另一个数据 结构,一个相当简单的结构:

    struct profile_city {
        /* btree pointers here */
        size_t profile_idx; /* or use a pointer */
        size_t city_idx;    /* for both indices */
    };
    

    所以,说Bob(简介4)已经访问了凤凰城(城市2) profile_idx = 4city_idx = 2。要说Bob已经访问过拉斯维加斯(城市 1)同样,你要添加另一个,所以你有两个给鲍勃。

    现在,您可以选择:您可以将它们存储在树或树中 哈希值。就个人而言,我会选择树,因为该代码已经存在 书面。但是对于查找,哈希将是O( n )而不是O(log n )。

    此外,就像我们为城市访问计数所做的那样,创建一个索引 city_idx因此也可以从该方面进行查找。

    结论

    现在,您可以通过有序的方式查找5个访问量最大的城市 遍历城市访问量指数),并找出谁访问这些 城市,通过搜索city_idx索引中的每个城市来获取 profile_idx。只抓住独特的物品,你有答案。

    哦,这里似乎有些不对劲:这似乎是一个非常多的代码,让您的教师想要在几个小时内写完!