当前位置: 首页 > 知识库问答 >
问题:

如何使用邻接表来表示具有虚拟顶点的图?

谭宜
2023-03-14

此图包含虚拟顶点。如何使用邻接表存储顶点的状态信息?应该存储每个顶点的输出边。

我用了简单的邻接表。但在这里,例如,v14有两组不同的输出边(一组没有输出边,另一组有两个输出边)。我应该使用什么数据结构来表示这样的虚拟节点。

共有1个答案

汪欣德
2023-03-14

由于您对实现没有约束,一个简单的类就可以了。在这里,我们将指向子级的(共享)指针存储在一个向量中。(重载)AddChild方法返回对添加的子项的引用,因此更容易将AddChild链接在一起。使用的操作符重载很好,但不是必需的,如果需要,您可以删除它们。代码如下:

#include <utility>
#include <iostream>
#include <string>
#include <vector>
#include <memory>

using std::vector;
using std::string;
using std::size_t;
using std::shared_ptr;
using std::make_shared;
using std::ostream;
using std::cout;
using std::endl;

class Node {
public:
  using child_ptr_type = shared_ptr<Node>;
  using contaner_type = vector<child_ptr_type >;

  explicit Node(string lab = "Default", contaner_type ch = {})
  : label(std::move(lab))
  , children(std::move(ch))
  {}

  const string &getLabel() const
  { return label; }

  void setLabel(const string &label)
  { Node::label = label; }

  const contaner_type &getChildren() const
  { return children; }

  const Node& getChild(size_t indx) const
  { return *children[indx]; }

  Node& getChild(size_t indx)
  { return *children[indx]; }

  Node& addChild(const string& lab = "Default", const contaner_type & ch = {})
  {
    children.push_back(make_shared<Node>(lab, ch));
    return *children.back();
  }

  Node& addChild(const child_ptr_type &child)
  {
    children.push_back(child);
    return *children.back();
  }

  Node& addChild(const Node& node)
  {
    children.push_back(make_shared<Node>(node));
    return *children.back();
  }

  friend ostream& operator<<(ostream& os, const Node &node)
  {
    node.print(os);
    return os;
  }

  Node&operator[](size_t indx)
  {
    return getChild(indx);
  }

  const Node&operator[](size_t indx) const
  {
    return getChild(indx);
  }



private:
  string label;
  contaner_type children;
  void print(ostream& os, size_t level = 0) const
  {
    for (size_t i = 0; i != level; ++i) {
      os << "|----";
    }
    os << label << '\n';
    for (const auto& child : children) {
      child->print(os, level + 1);
    }
  }
};

int main()
{
  Node V1("V1");

  V1.addChild("V2").addChild("V5").addChild("V7").addChild("V10");
  V1[0].addChild("V6").addChild("V8").addChild("V10");

  V1[0][1][0].addChild("V11").addChild("V13");
  V1[0][1][0].addChild("V14");

  V1.addChild("V3").addChild("V12").addChild("V14").addChild("V6");
  V1[1][0][0].addChild("V10");

  V1.addChild("V4").addChild("V13").addChild("V8");

  cout << V1 << endl;
  return 0;
}

main中的树是您在图片中的示例。输出如下:

V1
|----V2
|----|----V5
|----|----|----V7
|----|----|----|----V10
|----|----V6
|----|----|----V8
|----|----|----|----V10
|----|----|----|----V11
|----|----|----|----|----V13
|----|----|----|----V14
|----V3
|----|----V12
|----|----|----V14
|----|----|----|----V6
|----|----|----|----V10
|----V4
|----|----V13
|----|----|----V8
 类似资料:
  • `使用命名空间标准;

  • 在斯坦福的一门算法课程中,教授为图的邻接表表示列出了以下成分: 顶点数组或列表 边的数组或列表 顶点列表中的每个顶点都指向其上的边。 边列表中的每个边都指向其边点。 这种表示法与图形的“关联表”表示法相同吗?如果是,为什么本文认为“邻接表”和“发生率表”是分开的?

  • 我有一个无向加权图,作为邻接列表实现。有一个hashmap,其中节点对象作为键,边对象列表作为值。这些边对象包含两个节点之间边的权重。 我试图编写一个Dijkstra的最短路径算法;但是我担心我的图结构太复杂,无法理解我能为Dijkstra找到的所有示例/伪代码。有人能提供任何帮助吗?提前感谢。

  • 本文向大家介绍Dijkstra的邻接表表示算法,包括了Dijkstra的邻接表表示算法的使用技巧和注意事项,需要的朋友参考一下 有一个给定的图G(V,E)及其邻接列表表示形式,并且还提供了一个源顶点。Dijkstra的算法,用于找到源顶点与图G的任何其他顶点之间的最小最短路径。 为了解决这个问题,我们将使用两个列表。一种是存储已被视为最短路径树的顶点,另一种将保存尚未被考虑的顶点。在算法的每个阶段

  • 在书中,他们做过这样的宣示: 我应该如何将下面图的输入作为邻接表并输出它的邻接表表示?假设,edge的每个成本是10。

  • 我在这里读到,对于无向图,当表示为邻接表时,空间复杂度是,其中和分别是顶点和边的个数。 我的分析是,对于一个完全连通的图,列表中的每个条目将包含节点,那么我们总共有顶点,因此,空间复杂度似乎是这似乎是我在这里遗漏了什么?