7-1图论基础/7-2图的表示

 7-1图论基础

图由节点和边组成。

图的分类:

       有向图:边有方向

       无向图:边没有方向

       有权图:边有一个数值和其对应

       无权图: 和上面相反

       连通图:节点之间是否连通

       简单图:是否存在自环边(自己到自己)或者平行边(两个节点之间有多条边)

7-2图的表示

邻接矩阵:

 

邻接表:

邻接表适合表示稀疏图(边比较少,图中边的个数远远少于当图是完全图时的个数)

邻接矩阵适合表示稠密图(边比较多,如完全图,每两个节点之间都相连)

邻接表中查询是否已经存在边的操作,其时间复杂度是O(n),为了保证效率,在用邻接表表示图时,可以先不考虑平行边的问题

dense_graph.h:

#ifndef DENSE_GRAPH_H_INCLUDED
#define DENSE_GRAPH_H_INCLUDED

#include <iostream>
#include <vector>
#include <cassert>

using namespace std;

///稠密图----邻接矩阵

class DenseGraph{
private:
    int n;   /顶点的个数
    int m;   /边的个数
    vector<vector<bool>> g; 邻接矩阵
    bool directed;
public:


    /构造函数---顶点个数,是否是有向图
    DenseGraph(int n,bool directed)
    {
        n=n;
        directed=directed;
        m=0;

        创建n*n的矩阵
        for(int i=0;i<n;i++)
        {
            g.push_back(vector<bool>(n,false));

        }
    }

    析构函数
    ~DenseGraph(){}

    返回点的个数
    int V()
    {
        return n;
    }

    返回边的个数
    int E()
    {
        return m;
    }

    添加v和w之间的边
    void addEdge(int v,int w)
    {
        //判断v和w是否合法
        assert(v>=0 && v<n);
        assert(w>=0 && w<n);

        //判断v和w之间是否存在边,好处:自动去掉平行边
        if(hasEdge(v,w))
        {
            return ;
        }

        //添加从v->w的边
        g[v][w]=true;

        //如果是无向图
        if(!directed)
        {
            //添加从w->v的边
            g[w][v]=true;
        }

        //边数自增
        m++;
    }


    //判断v和w之间是否有边  //好处:O(1)的时间
    bool hasEdge(int v,int w)
    {
        assert(v>=0 && v<n);
        assert(w>=0 && w<n);
        return g[v][w];
    }


};


#endif // DENSE_GRAPH_H_INCLUDED

 

sparse_graph.h:

#ifndef SPARSE_GRAPH_H_INCLUDED
#define SPARSE_GRAPH_H_INCLUDED

#include <iostream>
#include <vector>
#include <cassert>

using namespace std;

//稀疏图---邻接表
class SparseGraph{
private:
    int n;  //点的个数
    int m;  //边的个数
    bool directed;  //是否有向
    vector<vector<int>> g;  //邻接表
public:
    //构造函数
    SparseGraph(int n,bool directed)
    {
        n=n;
        m=0;
        directed=directed;
        for(int i=0;i<n;i++)
        {
            g.push_back(vector<int>());

        }
    }

    //析构函数
    ~SparseGraph(){}

    int V()
    {
        return n;
    }

    int E()
    {
        return m;
    }


    void addEdge(int v,int w)
    {
        assert(v>=0&& v<n);
        assert(w>=0&& w<n);

        //先不管平行边,后面再进行处理
        g[v].push_back(w);
        if(!directed && v!=w) //v=w表示是自环边,自环边只添加一次
        {
            g[w].push_back(v);
        }
        m++;
    }

    bool hasEdge(int v,int w)
    {
        assert(v>=0&& v<n);
        assert(w>=0&& w<n);

        for(int i=0;i<g[v].size();i++)
        {
            if(g[v][i]==w)
            {
                return true;
            }
        }
        return false;
    }



};

#endif // SPARSE_GRAPH_H_INCLUDED

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值