在这篇文章中,我们要讨论一下关于图的知识点:

1.图的存储方式——邻接矩阵存储和邻接表存储

*邻接矩阵存储code如下所示

#include 
 
using namespace std;
 
template 
class Graph
{
protected:
    int n,e;                                     //e是边数,n是节点数
public:
    virtual bool GInsert(int u,int v,T w)=0;   //图中在节点u和v之间插入一条权值为w的边
    virtual bool GRemove(int u,int v)=0;        //删除图中节点u和v之间的边
    virtual bool GExist(int u,int v) const=0;    //判断图中节点u和v之间是否存在路径
};
 
template 
class MGraph:public Graph
{
protected:                          //这里用protected权限是为了未来可能存在的继承该MGraph的类可以访问
    T **a;                          //二维数组指针指向图的邻接矩阵
public:
    MGraph(int mSize);
    ~MGraph();
    bool GInsert(int u,int v,T w);
    bool GRemove(int u,int v);
    bool GExist(int u, int v)const;
};
template 
MGraph::MGraph(int mSize)               //邻接矩阵是n*n的大小,即有n个节点
{
    n=mSize;
    a=new T* [n];                   //申请一个大小为n的T*指针类型数组空间,每个空间存储一个T指针
    for(int i=0;i
MGraph::~MGraph()
{
    for(int i=0;i
bool MGraph::GInsert(int u, int v, T w)
{
    if(u<0||v<0||u>n-1||v>n-1)
    {
        cout<<"节点值越界"<
bool MGraph::GRemove(int u,int v)
{
    if(u<0||v<0||u>n-1||v>n-1)
    {
        cout<<"节点值越界"<
bool MGraph::GExist(int u, int v) const
{
    if(u<0||v<0||u>n-1||v>n-1)
    {
        cout<<"GExit:节点越界"< a(4);
    a.GInsert(0,1,1);
    a.GExist(0,2);
    return 0;
}

*邻接表类似于一个哈希表,邻接表存储方式的图code如下所示

#include 
using namespace std;
 
template  class LGraph;
template 
class LNode                 //邻接表节点类
{
private:
    int adjVex;             //节点号
    T w;                    //边权值
    LNode *nextArc;      //节点指针
public:
    LNode(int vertex,T weight,LNode *next)
    {
        adjVex=vertex;
        w=weight;
        nextArc=next;
    }
 
    friend class LGraph; //友元类LGraph可以访问类LNode中的private成员
};
 
template 
class LGraph                //邻接表类
{
private:
    LNode **a;           //邻接表二维指针
    int n;                  //图的节点数
    int e;                  //图的边数
public:
    LGraph(int mSize);
    ~LGraph();
    bool LExist(int u,int v);
    bool LInsert(int u,int v,T w);
    bool LRemove(int u,int v);
};
 
template
LGraph::LGraph(int mSize)    //初始化邻接表
{
    n=mSize;
    a=new LNode* [n];
    for(int i=0;i
LGraph::~LGraph()
{
    for(int i=0;i
bool LGraph::LExist(int u,int v)
{
    if(u<0||v<0||u>n-1||v>n-1)
    {
        cout<<"LExist:节点号越界"<<'\n';
        return false;
    }
    LNode *p=a[u];
    while(p)
    {
        if(p->adjVex==v)
        {
            cout<<"LExist:存在"<nextArc;
    }
    if(!p)
        return false;
}
 
template
bool LGraph::LInsert(int u,int v,T w)
{
    if(u<0||v<0||u>n-1||v>n-1)
    {
        cout<<"LInsert:节点号越界"<<'\n';
        return false;
    }
    if(LExist(u,v))
    {
        cout<<"LInsert:已经存在"< *p=new LNode(v,w,a[u]);
    a[u]=p;
    e++;
    return true;
}
 
template
bool LGraph::LRemove(int u,int v)
{
    if(u<0||v<0||u>n-1||v>n-1)
    {
        cout<<"LRemove:节点号越界"<<'\n';
        return false;
    }
    if(!LExist(u,v))
    {
        cout<<"LRemove:不存在"< *p=a[u],*q=NULL;
    while(p&&p->adjVex!=v)
    {
        q=p;
        p=p->nextArc;
    }
    if(!p)
        return false;
    if(q)
        q->nextArc=p->nextArc;
    else
        a[u]=p->nextArc;
    delete p;
    e--;
    return true;
}

2.图的深度优先遍历(DFS),这里我们讨论以邻接表形式存储的图如何进行深度优先遍历。这里采用了递归法,大致思路如下

(1)访问任意节点v,并对v打上已经访问过的标记

(2)依次从v的未访问邻接点出发,深度优先搜索图

#include "lgraph.cpp"
 
//图的搜索
template 
class ExtLGraph:public LGraph
{
private:
    void DFS(int v,bool *visited);          //从v节点出发深度优先搜索,visited是标志位数组指针
    //void BFS();
public:
    ExtLGraph(int mSize):LGraph(mSize){} //调用父类的构造函数来初始化子类构造函数
    void DFS();                             //深度优先遍历
    //void BFS();                               //宽度优先遍历
};
template 
void ExtLGraph::DFS()
{
    bool *visited=new bool [n];             //创建标志位数组
    for(int i=0;i
void ExtLGraph::DFS(int v,bool *visited)
{
    visited[v]=true;                        //v节点标志位至为true
    cout<<" "< *p=a[v];
    while(p)
    {
        if(!visited[p->adjVex])
            DFS(p->adjVex,visited);
        p=p->nextArc;
    }
    
}

注意:由于ExtLGraph类是LGraph的子类,由于友元类无法继承的原因,在ExtLGraph类中无法访问LNode类中的private成员,因此LNode类中应该将ExtLGraph类设置为友元类!!!

你可能感兴趣的:(图)