在C ++中为通用图实现Hierholzer算法

时间:2013-10-25 12:41:36

标签: c++ algorithm graph

我有一个节点(基本上是图形顶点模板化类,如下所示:

template<class T>
class Node
{
   public:
      T Data;
      Node<T>* Parent;
      vector<Node<T>*> Children;
};

然后我有一个模板化的图形类,它封装了图形的根,我有一个方法,它应该生成一个欧拉路径(在它检查了是否满足欧拉路径存在的条件之后):

template<class T>
class Graph
{
   public:
      Node<T>* Root;

      vector<Node<T>*> GetEulerianPath() const;
      bool HasEulerianPath() const;
};

HasEulerianPath()只是遍历节点(* 顶点 *)层次结构并计算具有奇数度的顶点数量。如果它们不超过两个,它返回真实。

现在的问题是 - 我不太确定如何实现算法。有什么提示?我应该只是在向量中提取整个层次结构并迭代到那个或者我是否使用了一些节点的递归方法?Wikipedia Page建议使用链表 ...或者我应该只生成一个新的更小的单向作为 GetEulerianPath()方法的输出?我对如何继续这里感到困惑。

2 个答案:

答案 0 :(得分:0)

您需要先转换图表。但绝对不是std :: vector。

对于每个节点,您需要能够快速获得未使用的边缘(将它们全部放在链接列表中并在使用时删除)。

因此,每个节点都应该有一个子列表,而不是std :: vector。

接下来,您需要能够找到具有未使用边缘的节点,您可以在遍历时收集链接列表中的节点。您还需要在遍历时使用路径构建链接列表,未使用的边缘列表应引用此列表,以便您可以在O(1)中更改路径。

(代码中的Node<T>* Parent;对于一般图表来说似乎很奇怪。)

答案 1 :(得分:0)

您构建Node类的方式基本上形成了一个包含在vector中的双向链表。您似乎有一些问题(数学上):

给定的“孩子”可以有超过1个“父母”。事实上,如果有2个“子”节点,那么作为2个“父”节点,以使其成为欧拉循环。您可能需要重新定义Node,如下所示:

template<class T>
class Node
{
   public:
      T Data;
      list<shared_ptr<Node<T>>> Connections;
};

您可以将Graph更改为:

template<class T>
class Graph
{
   public:
      shared_ptr<Node<T>> Start; // name change just to convey that there isn't a "root" node in an Eulerian cycle

      list<shared_ptr<Node<T>>> GetEulerianPath() const;
      bool HasEulerianPath() const;
};

这样,实现Hierholzer算法只需遍历每个节点的Connections