Data structures 图-如果我用哈希表替换邻接列表中的每个链表,有什么缺点?

Data structures 图-如果我用哈希表替换邻接列表中的每个链表,有什么缺点?,data-structures,graph,hashtable,adjacency-list,Data Structures,Graph,Hashtable,Adjacency List,CLRS练习22.1-8(我是自学,不是在任何大学) 假设每个数组条目Adj[u]不是链表,而是一个 包含顶点v的哈希表,其中(u,v)∈ E.如果有的话 边缘查找的可能性同样大,预计查找的时间是多少 确定边是否在图形中?它有什么缺点 这项计划有什么好处?为每个边缘建议一个备用数据结构 列出解决这些问题的方法。你的替代方案有没有 与哈希表相比的缺点是什么 因此,如果我用哈希表替换每个链表,有以下问题: 确定边是否在图形中的预期时间是多少 缺点是什么 为解决这些问题的每个边缘列表建议一个备用数据结

CLRS练习22.1-8(我是自学,不是在任何大学)

假设每个数组条目Adj[u]不是链表,而是一个 包含顶点v的哈希表,其中(u,v)∈ E.如果有的话 边缘查找的可能性同样大,预计查找的时间是多少 确定边是否在图形中?它有什么缺点 这项计划有什么好处?为每个边缘建议一个备用数据结构 列出解决这些问题的方法。你的替代方案有没有 与哈希表相比的缺点是什么

因此,如果我用哈希表替换每个链表,有以下问题:

  • 确定边是否在图形中的预期时间是多少
  • 缺点是什么
  • 为解决这些问题的每个边缘列表建议一个备用数据结构
  • 与哈希表相比,您的备选方案有缺点吗
  • 我有以下部分答案:

  • 我认为预期的时间是O(1),因为我只是去Hashtable t=Adj[u],然后返回t.get(v)
  • 我认为缺点是哈希表比链表占用更多的空间
  • 至于另外两个问题,我一点也不知道


    任何人都可以给我一个线索吗?

    这取决于哈希表以及它如何处理冲突,例如,假设在我们的哈希表中,每个入口指向具有相同键的元素列表

    如果元素的分布足够均匀,则查找的平均成本仅取决于每个列表的平均元素数(负载系数)。所以每个列表的平均元素数是n/m,其中m是哈希表的大小

  • 确定边是否在图形中的预期时间为O(n/m)
  • 比链表更大的空间和比邻接矩阵更多的查询时间。如果我们的哈希表支持动态调整大小,那么我们将需要额外的时间在旧哈希表和新哈希表之间移动元素,如果不支持,则每个哈希表都需要O(n)个空间,以便有O(1)个查询时间,这将导致O(n^2)个空间。此外,我们刚刚检查了预期的查询时间,在最坏的情况下,我们可能会有查询时间,就像链表一样(O(度(u)),所以最好使用邻接矩阵来确定O(1)查询时间和O(n^2)空间
  • 读上面
  • 是的,例如,如果我们知道图的每个顶点最多有d个相邻顶点,并且d小于n,那么使用哈希表将需要O(nd)空间,而不是O(n^2),并且预计需要O(1)查询时间

  • 问题3的答案可能是一个二叉搜索树

    在邻接矩阵中,每个顶点后跟一个V元素数组。这种O(V)-空间代价导致快速(O(1)-时间)搜索边

    在邻接列表中,每个顶点后面都有一个列表,该列表仅包含n个相邻顶点。这种节省空间的方法导致搜索速度慢(O(n))

    哈希表是数组和列表之间的折衷方案。它使用的空间比V小,但在搜索时需要处理冲突


    二叉搜索树是另一种折衷方法——空间开销与列表一样最小,搜索的平均时间开销为O(lg n)。

    问题3和4非常开放。除了其他两种方法的思想之外,哈希表的一个问题是它不是一种从开始到结束扫描元素的有效数据结构。在现实世界中,有时枚举给定顶点的所有邻居(例如BFS、DFS)是非常常见的,这在某种程度上影响了直接哈希表的使用

    一种可能的解决方案是将哈希表中现有的bucket链接在一起,以便它们形成一个双链接列表。每次添加新元素时,将其连接到列表的末尾;每当删除某个元素时,请将其从列表中删除,并相应地修复链接关系。当你想进行全面扫描时,只需浏览一下这个列表

    当然,这种策略的缺点是空间更大。每个元素都有两个指针开销。此外,添加/删除元素需要更多的时间来构建/修复链接关系


    我不太担心碰撞。顶点的哈希表存储其邻居,每个邻居都是唯一的。如果它的键是唯一的,就没有冲突的可能。

    我喜欢你的答案。我的想法是一样的,即用红黑/自平衡树替换列表。或者列表可以保持排序顺序。“如果它的键是唯一的,就不会发生冲突。”冲突的整个点是两个不同的键散列到相同的值,而不是两个键是相同的