C++算法从入门到放弃-无向图(1)

来源:互联网 发布:淘宝复核阿里钱盾 编辑:程序博客网 时间:2024/06/07 02:00

April 8, 2016

    • API
    • 图的表示
    • 图的数据结构
    • 实现

API

class Graph{private:    int _v;    int _e;    std::map<int, std::vector<int>> adjMartix;public:    using Iterator = std::map<int, std::vector<int>>::iterator;    using Const_Iterator = std::map<int, std::vector<int>>::const_iterator;    Graph() = delete;    Graph(int V):_v(V), _e(0)    {        std::vector<int> temp;        for(int i = 0; i < V; ++i){            this->adjMartix.insert(std::pair<int, std::vector<int>>(i, temp));        }    }    Graph(const Graph& other);    Graph& operator=(const Graph& other);    int V() { return _e; }    int E() { return _e; }    void addEdge(int v, int w);    std::vector<int> adj(int v);    int degree(int v);    int maxDegree();    double avgDegree();    int numberOfselfLoops();    std::string toString(std::ostream& os);};

图的表示

  • 邻接矩阵。不能满足存储平行边的需求,放弃。
bool edge[M][N];
  • 边的数组。如果要找出和某一顶点相邻的所有顶点那么就要遍整个数组,放弃。
struct Edge{    int v;    int w;};std::vector<Edge> allEdge;
  • 邻接表数组满足需求而且空间要求仅为顶点数的两倍(不考虑顺序容器的开销)。
std::map<int,std::vector<int>> allEdge;

图的数据结构

使用邻接表数组表示的图有如下特点:

  • 使用的空间和V+E成正比
  • 添加一条边所需要的时间为常数
  • 遍历顶点v的所有相邻顶点所需的时间和v的度数成正比(处理每个相邻顶点所需要的时间为常数)

实现

Graph::Graph(const Graph & other){    this->_v = other._v;    this->_e = other._e;    this->adjMartix = other.adjMartix;}Graph & Graph::operator=(const Graph & other){    this->_v = other._v;    this->_e = other._e;    this->adjMartix = other.adjMartix;    return *this;}void Graph::addEdge(int v, int w){    Graph::Iterator it = this->adjMartix.find(v);    (*it).second.push_back(w);    ++(this->_e);}std::vector<int> Graph::adj(int v){    return (this->adjMartix).find(v)->second;}int Graph::degree(int v){    Graph::Const_Iterator cit = this->adjMartix.find(v);    return (*cit).second.size();}int Graph::maxDegree(){    unsigned max = 0;    for each (auto var in this->adjMartix)    {        if(var.second.size() > max)            max = var.second.size();    }    return max;}double Graph::avgDegree(){    return E() / V()*2.0;}int Graph::numberOfselfLoops(){    int count = 0;    for(int v = 0; v < V(); v++){        for each (auto var in adj(v))        {            if(v == var)                ++count;        }    }    return count / 2;}std::string Graph::toString(std::ostream& os){    std::stringstream ss;    ss << this->_v << " vertices. " << this->_e << " edges\n";    for(int v = 0; v < (this->_v); ++v){        ss << v << ": ";        for each (auto var in this->adj(v))        {            ss << var << " ";        }        ss << "\n";    }    os << ss.str();    return ss.str();}
0 0