我正在做的这个程序是关于社交网络,这意味着有用户及其个人资料。配置文件结构为UserProfile
。
现在,有各种可能的Graph实现,我认为我没有使用最好的。我有一个Graph
结构,里面有一个指向Vertex
类型链表的指针。每个Vertex
元素都有一个值,一个指向下一个Vertex
的指针和一个指向类型Edge
的链接列表的指针。每个Edge
元素都有一个值(所以我可以定义权重及其所需的值),指向下一个Edge
的指针和指向Vertex
所有者的指针。
我有2个样本文件,其中包含要处理的数据(CSV格式)并插入图表。第一个是用户数据(每行一个用户);第二个是用户关系(对于图表)。第一个文件快速插入到图形中,因为我总是插入头部,大约有18000个用户。第二个文件需要很长时间,但我仍然将边缘插入头部。该文件具有大约~520000行的用户关系,需要13-15分钟才能插入图表。我进行了快速测试,并且非常快速,即时地读取数据。问题在于插入。
这个问题的存在是因为我有一个用顶点的链表实现的图。每次我需要插入关系时,我需要查找2个顶点,因此我可以将它们链接在一起。这就是问题......为~520000关系这样做需要一段时间。
我该如何解决这个问题?
解决方案1)有人建议我将Graph(顶点部分)实现为数组而不是链表。这样我可以直接访问每个顶点,插入可能会大大减少。但是,我不喜欢用[18000]元素分配数组的想法。这有多实际?我的样本数据大约有18000,但是如果我需要更少或更多的话呢?链表方法具有这种灵活性,只要有内存,我就可以拥有我想要的任何大小。但阵列没有,我怎么处理这种情况呢?你有什么建议吗?
使用链表有利于空间复杂性,但对时间复杂性不利。使用数组有利于时间复杂性,但对空间复杂性不利。
对此解决方案的任何想法?
解决方案2)此项目还要求我拥有某种数据结构,允许基于名称索引和ID索引进行快速查找。为此,我决定使用哈希表。我的表是使用单独的链接作为冲突解决方案实现的,当达到0.70的加载因子时,我通常会重新创建表。我将下一个表格大小基于http://planetmath.org/encyclopedia/GoodHashTablePrimes.html。
目前,两个哈希表都包含指向UserProfile
的指针,而不是复制用户配置文件本身。这将是愚蠢的,改变数据将需要3次更改,这样做真的很蠢。所以我只是将指针保存到UserProfile
。相同的用户配置文件指针也会在每个图表Vertex
中保存为值。
因此,我有3个数据结构,一个Graph和两个Hash表,并且每一个都指向相同的UserProfile
。 Graph结构将用于查找最短路径和类似内容,而Hash Tables则按名称和ID作为快速索引。
我正在考虑解决我的图形问题的方法是,不是将哈希表值指向UserProfile
,而是将其指向相应的Vertex
。它仍然是一个指针,没有更多,也没有更少的空间使用,我只是改变我指向的。
像这样,我可以轻松快速地查找我需要的每个顶点并将它们链接在一起。这将很快插入~520000关系。
我想到了这个解决方案,因为我已经有了Hash Tables,我需要拥有它们,那么,为什么不利用它们来索引Graph顶点而不是用户配置文件呢?这基本上是一回事,我仍然可以很快访问UserProfile
,只需转到Vertex
然后转到UserProfile
。
但是,你认为第二个解决方案对第一个解决方案有任何缺点吗?或者只有专业人士在第一个解决方案上胜过利弊?
其他解决方案)如果您有任何其他解决方案,我会全力以赴。但请解释前一个解决方案的优缺点。我现在真的没有太多时间浪费这个,我需要继续这个项目,所以,如果我这样做的话如果发生变化,我需要准确理解要改变的内容以及是否真的要走了。
希望没有人在阅读此内容时睡着了并关闭浏览器,对于大遗嘱感到遗憾。但我真的需要决定该怎么办,我真的需要做出改变。
P.S:在回答我提出的解决方案时,请按照我的方式列举它们,所以我确切地知道你在说什么,不要比我自己更加困惑。
答案 0 :(得分:1)
第一种方法是由于这里的主要问题是速度,我更喜欢阵列方法。
当然,您应该维护名称索引查找的哈希表。
如果我理解正确,您只需处理一次数据。因此没有动态数据插入。
为了解决空间分配问题,我建议:
1 - 读取一次文件,获取顶点数。
2 - 分配该空间
如果您的数据是动态的,您可以实现一些简单的方法,以50%的步长递增数组大小。
3 - 在边缘中,用链接列表替换数组。该数组应以50%的步长动态递增。
即使分配了“额外”空间,当您以50%的步长递增大小时,数组使用的总大小应仅略大于链接列表的大小。
我希望我能提供帮助。