繁体   English   中英

如何从有向图中删除边和顶点

[英]How to delete edge and vertices from directed graph

给定uv我想从邻接列表图中删除u顶点和u,v边。 我遵循的方法是从根和其他根的其他集合中删除顶点。

例子:

我想删除顶点 u

u -> a b c d
x -> u   // u should be deleted

这是我的 class 的简要说明:

template <class T>
class Digraph
{
public:
    Digraph();
    ~Digraph();

void delete_vertex(T u);
void delete_edge(T u, T v);


private:
    std::map<T, std::set<T>> graph;
}

我尝试了什么:

template <class T>
void Digraph<T>::delete_vertex(T u)
{
    graphe.erase(u);

    for (auto const &pair : graphe)
    {
        for (auto const &elem : pair.second)
        {
            if(elem == u){
                pair->second.erase(u);
            }
        }
    }
}

template <class T>
void Digraph<T>::delete_edge(T u, T v)
{
    std::set<T> s = graphe[u];
    s.erase(v);
}

我想知道我在 delete_vertex function 中所做的是否正确,因为它不起作用,也许我忘记了什么,有人可以帮我吗?

这两个函数都被窃听了。 delete_edge的问题在于您正在复制边集,然后从副本中删除而不是从原始中删除。 这是初学者常见的错误,将 C++ 对象视为引用,而实际上它们不是。 这是真正使用参考的版本

template <class T>
void Digraph<T>::delete_edge(T u, T v)
{
    std::set<T>& s = graphe[u]; // s is a reference
    s.erase(v);
}

但只是消除变量更简单(恕我直言)

template <class T>
void Digraph<T>::delete_edge(T u, T v)
{
    graphe[u].erase(v);
}

delete_vertex的问题正如一些程序员老兄所说,如果你正在迭代它,你不能从容器中删除。 这是一个基于迭代器的解决方案

template <class T>
void Digraph<T>::delete_vertex(T u)
{
    graphe.erase(u);
    for (auto const &pair : graphe)
    {
        auto i = pair.second.begin();
        while (i != pair.second.end())
        {
            if (*i == u)
                i = pair.second.erase(i);
            else
                ++i;
        }
    }
}

在指向已擦除元素的迭代器上使用++甚至是非法的,这就是为什么erase返回指向下一个元素的迭代器的原因。

未经测试的代码,所以对任何错误表示歉意。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM