C++ 使用multimap c+;打印邻接列表+;

C++ 使用multimap c+;打印邻接列表+;,c++,graph,map,C++,Graph,Map,我基于以下链接构建了一个邻接列表: struct节点 { 字符串名; int-id; }; typedef-std::多映射图; 图g; g、 插入(图形::值_类型(节点1、节点3)); g、 插入(图形::值_类型(节点1、节点4)); g、 插入(图形::值_类型(节点1、节点5)); g、 插入(图形::值_类型(节点2、节点6)); g、 插入(图形::值_类型(节点3、节点6)); 如何按照下图()的结构打印多重贴图 如果您不想进行冗余的equal_range调用,只要两

我基于以下链接构建了一个邻接列表:


struct节点
{
字符串名;
int-id;
};
typedef-std::多映射图;
图g;
g、 插入(图形::值_类型(节点1、节点3));
g、 插入(图形::值_类型(节点1、节点4));
g、 插入(图形::值_类型(节点1、节点5));
g、 插入(图形::值_类型(节点2、节点6));
g、 插入(图形::值_类型(节点3、节点6));

如何按照下图()的结构打印多重贴图


如果您不想进行冗余的
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;
}
Graph::key\u compare cmp=g.key\u comp();
图::const_迭代器it=g.begin(),itEnd=g.end(),prev;
while(it!=itEnd)
{
std::cout first);

std::cout以下替代解决方案使用C++11的基于范围的for循环。它迭代所有条目,而不管源节点如何,并将当前源节点与前一个源节点进行比较。如果它们不同,则在输出中开始一个新行

与使用
equal_range
的解决方案相比,此替代方案对缓存更加友好:它只按节点顺序在整个图上迭代一次。
equal_range
首先使用相同的源节点搜索范围的结尾,然后循环再次在这些元素上迭代。我的替代解决方案tion避免了这一点(当然,我没有做基准测试,这并不是说这是最终最快的解决方案,但我只是想提供一个替代方案)


我错过了这个,+2WTWONK<代码>范围。第二次/代码>被重用以推进<代码> it >代码>,即代码< >代码范围>第二个/代码>循环结束。考虑<代码>图< /代码>可能不使用<代码> STD::小于< /代码>作为排序谓词,所以<代码> E.第一个Prave<代码>可能不总是工作,只需替换<代码> CMP(E.第一,PREV)
对于
图形::key_compare cmp=g.key_comp()
-无需同时检查
e.first
,因为迭代器是按顺序排列的(第一个不小于下一个元素,因为它不能大于,所以它必须等于)äh抱歉
cmp(prev,e.first)
而不是反过来!
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,
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;
}
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;
}
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;
}