我根据以下链接构建了一个邻接列表:Adjacency list
struct Node
{
string name;
int id;
};
typedef std::multimap<Node,Node> Graph;
Graph g;
g.insert (Graph::value_type(node1, node3));
g.insert (Graph::value_type(node1, node4));
g.insert (Graph::value_type(node1, node5));
g.insert (Graph::value_type(node2, node6));
g.insert (Graph::value_type(node3, node6));
如何按照下图(Adjacency list)的结构打印多图?
答案 0 :(得分:3)
Graph::const_iterator it = g.begin();
while (it != g.end())
{
std::pair<Graph::const_iterator, Graph::const_iterator> range
= g.equal_range(it->first);
std::cout << it->first << ": "; // print vertex
for (; range.first != range.second; ++range.first)
{
std::cout << range.first->second << ", "; // print adjacent vertices
}
std::cout << std::endl;
it = range.second;
}
输出:
1: 3, 4, 5,
2: 6,
3: 6,
4: 7,
5: 7, 8, 9,
9: 5,
如果您不想进行冗余 equal_range
调用,只要两个相邻的元素相等,就可以使用单个迭代器进行操作订购条款:
Graph::key_compare cmp = g.key_comp();
Graph::const_iterator it = g.begin(), itEnd = g.end(), prev;
while (it != itEnd)
{
std::cout << it->first << ": "; // print vertex
do
{
std::cout << it->second << ", "; // print adjacent vertices
prev = it++;
}
while (it != itEnd && !cmp(prev->first, it->first));
std::cout << std::endl;
}
答案 1 :(得分:2)
以下替代解决方案使用C ++ 11的基于范围的for循环。它遍历所有条目,无论源节点如何,并将当前源节点与前一个节点进行比较。如果它们不同,请在输出中开始一个新行。
与使用equal_range
的解决方案相比,此替代方案更加缓存友好:它只按节点的顺序迭代整个图形。 equal_range
首先使用相同的源节点搜索范围的结尾,然后循环再次遍历这些元素。我的替代解决方案避免了这一点(当然,我没有做任何基准测试,这不是最终的最快解决方案,但我只想提供替代方案。)
std::ostream& operator<<(std::ostream& os, const Graph& g)
{
auto prev = g.begin()->first;
os << prev << ": ";
for (auto e : g) {
if (e.first < prev || prev < e.first)
os << std::endl << (prev = e.first) << ": ";
os << e.second << ", ";
}
return os << std::endl;
}
如果您为operator!=
类型实施Node
,则if
- 行可以简化为更具可读性的比较:
std::ostream& operator<<(std::ostream& os, const Graph& g)
{
auto prev = g.begin()->first;
os << prev << ": ";
for (auto e : g) {
if (e.first != prev) // <--- now more readable
os << std::endl << (prev = e.first) << ": ";
os << e.second << ", ";
}
return os << std::endl;
}