我正在做的这个程序是关于一个社交网络的,这意味着有用户和他们的个人资料。配置文件结构是UserProfile
.
现在,有各种可能的 Graph 实现,我认为我使用的不是最好的。我有一个Graph
结构,里面有一个指向 type 的链表的指针Vertex
。每个Vertex
元素都有一个值、一个指向下一个元素的指针Vertex
和一个指向类型链表的指针Edge
。每个Edge
元素都有一个值(所以我可以定义权重和需要的任何东西)、一个指向下一个元素的指针Edge
和一个指向Vertex
所有者的指针。
我有 2 个示例文件,其中包含要处理的数据(以 CSV 样式)并插入到图表中。第一个是用户数据(每行一个用户);第二个是用户关系(用于图表)。第一个文件很快被插入到图表中,因为我总是在头部插入并且有大约 18000 个用户。第二个文件需要很长时间,但我仍然在头部插入边缘。该文件有大约 520000 行用户关系,需要 13-15 分钟才能插入到图表中。我做了一个快速测试,读取数据非常快,真的是瞬间。问题在于插入。
存在这个问题是因为我有一个用顶点的链表实现的 Graph。每次我需要插入关系时,我都需要查找 2 个顶点,以便将它们链接在一起。这就是问题所在......为〜520000个关系执行此操作需要一段时间。
我应该如何解决这个问题?
解决方案 1)有人建议我将 Graph(顶点部分)实现为数组而不是链表。这样我就可以直接访问每个顶点,并且插入可能会大大减少。但是,我不喜欢使用 [18000] 元素分配数组的想法。这有多实用?我的样本数据有 ~18000,但如果我需要更少或更多怎么办?链表方法具有这种灵活性,只要有内存,我就可以拥有我想要的任何大小。但是数组没有,我将如何处理这种情况?你有什么建议?
使用链表有利于空间复杂度,但不利于时间复杂度。使用数组有利于时间复杂度,但不利于空间复杂度。
关于这个解决方案的任何想法?
解决方案 2)这个项目还要求我有某种数据结构,允许基于名称索引和 ID 索引进行快速查找。为此,我决定使用哈希表。我的表是通过单独的链接作为冲突解决方案实现的,当达到 0.70 的负载因子时,我通常会重新创建表。我将下一个表大小基于此Link。
目前,两个哈希表都持有一个指向UserProfile
而不是重复用户配置文件本身的指针。那将是愚蠢的,更改数据将需要 3 次更改,这样做真的很愚蠢。所以我只是将指针保存到UserProfile
. 相同的用户配置文件指针也保存为每个 Graph 中的值Vertex
。
所以,我有 3 个数据结构,一个 Graph 和两个 Hash Tables,每一个都指向同一个 exact UserProfile
。Graph 结构将用于查找最短路径和类似的东西,而 Hash Tables 用作按名称和 ID 的快速索引。
我正在考虑解决我的 Graph 问题是,而不是让 Hash Tables 值指向 ,而是将其UserProfile
指向相应的Vertex
. 它仍然是一个指针,没有更多也没有更少的空间使用,我只是改变我指向的内容。
像这样,我可以轻松快速地查找我需要的每个顶点并将它们链接在一起。这将很快插入 ~520000 个关系。
我想到了这个解决方案,因为我已经有了哈希表并且我需要它们,那么,为什么不利用它们来索引 Graph 顶点而不是用户配置文件呢?基本上是一样的,我仍然可以UserProfile
很快访问,只需转到Vertex
然后到UserProfile
.
但是,您认为第二个解决方案与第一个解决方案相比有什么缺点吗?还是只有在第一个解决方案中胜过利弊的利弊?
其他解决方案)如果您有任何其他解决方案,我会全力以赴。但是请解释一下该解决方案与前两个相比的优缺点。我现在真的没有太多时间可以浪费在这个问题上,我需要继续这个项目,所以,如果我这样做的话改变,我需要确切地了解要改变什么,如果这真的是要走的路。
希望没有人在阅读这篇文章后睡着了并关闭了浏览器,对于大遗嘱感到抱歉。但我真的需要决定如何解决这个问题,我真的需要做出改变。
PS:在回答我提出的解决方案时,请像我一样列举它们,这样我就知道你在说什么,并且不要比我现在更迷惑我自己。