菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
252
0

图的存储结构

原创
05/13 14:22
阅读数 65016

声明:图片及内容基于https://www.bilibili.com/video/BV1Qf4y1m77B?from=articleDetail

邻接矩阵(数组表示法)

无向图的邻接矩阵

 

有向图的邻接矩阵

网图的邻接矩阵

邻接矩阵存储有向网图代码

类的声明

template <class T>
class MGraph {
    private:
        T *vertex;         //顶点信息
        int **arc; //邻接矩阵
        int vertexNum,arcNum;        //顶点数,边数
    public:
        MGraph(T v[],int n,int e);
        ~MGraph();
        void DFSTraverse(int v);
        void BFSTraverse(int v);
        void display();
};

构造函数

template <class T>
MGraph<T>::MGraph(T v[],int n,int e) {  //n是顶点数,e是边数
    vertexNum=n;
    arcNum=e;
    vertex = new T[vertexNum];         //建立顶点信息
    arc = new int*[vertexNum];         //建立邻接表
    for(int i=0; i<vertexNum; i++)
        arc[i]=new int[vertexNum];

    for(int i=0; i<vertexNum; i++) {   //初始化顶点信息 
        vertex[i]=v[i];
    }
    for(int i=0;i<vertexNum;i++)       //初始化邻接表 
        for(int j=0;j<vertexNum;j++){
            if(i==j)     arc[i][j]=0;
            else     arc[i][j]=INFINIT;
        }
            
    int vi,vj,w;
    for(int i=0;i<arcNum;i++){
        cout<<"请输入边的两个顶点和这条边的权值"<<endl; 
        cin>>vi>>vj>>w;   //输入边依附的两个顶点的编号 和权值 
        arc[vi][vj]=w; //有边标志 
    }
}

 

完整代码

#include<iostream>
using namespace std;
const int INFINIT=65535;
template <class T>
class MGraph {
    private:
        T *vertex;         //顶点信息
        int **arc;         //邻接矩阵
        int vertexNum,arcNum;        //顶点数,边数
    public:
        MGraph(T v[],int n,int e);
        ~MGraph();
        void DFSTraverse(int v);
        void BFSTraverse(int v);
        void display();
};
template <class T>
MGraph<T>::MGraph(T v[],int n,int e) {  //n是顶点数,e是边数
    vertexNum=n;
    arcNum=e;
    vertex = new T[vertexNum];         //建立顶点信息
    arc = new int*[vertexNum];         //建立邻接表
    for(int i=0; i<vertexNum; i++)
        arc[i]=new int[vertexNum];

    for(int i=0; i<vertexNum; i++) {   //初始化顶点信息 
        vertex[i]=v[i];
    }
    for(int i=0;i<vertexNum;i++)       //初始化邻接表 
        for(int j=0;j<vertexNum;j++){
            if(i==j)     arc[i][j]=0;
            else     arc[i][j]=INFINIT;
        }
            
    int vi,vj,w;
    for(int i=0;i<arcNum;i++){
        cout<<"请输入边的两个顶点和这条边的权值"<<endl; 
        cin>>vi>>vj>>w;   //输入边依附的两个顶点的编号 和权值 
        arc[vi][vj]=w; //有边标志 
    }
}

template <class T>
void MGraph<T>::display(){
    for(int i=0;i<vertexNum;i++){
        for(int j=0;j<vertexNum;j++){

      if(arc[i][j]==INFINIT)
        cout<<"∞"<<"\t";
      else cout<<arc[i][j]<<"\t";

        }
        cout<<endl;
    }
    cout<<endl;

    for(int i=0;i<vertexNum;i++){
        cout<<vertex[i]<<" ";
    }
}

template <class T>
MGraph<T>::~MGraph(){
    delete []vertex;
    for(int i=0;i<vertexNum;i++)
        delete [] arc[i];
    delete [] arc;
}
int main(){
    char* v[5]={"v0","v1","v2","v3","v4"};
    MGraph<char*> mgraph(v,5,6);
    mgraph.display();
    return 0;
}

输入:

1 0 9

2 0 2

0 4 6

2 3 5

3 4 1

1 2 3

输出:

0 ∞ ∞ ∞ 6
9 0 3 ∞ ∞
2 ∞ 0 5 ∞
∞ ∞ ∞ 0 1
∞ ∞ ∞ ∞ 0

v0 v1 v2 v3 v4

邻接表

定义

 

无向图的邻接表

有向图的邻接表

网图的邻接表

邻接表中图的基本操作

完整代码

#include<iostream>
using namespace std;
const int MAX=10;
typedef struct ArcNode{     //边结点 
    int adjvex;          //存储图中结点下标
    ArcNode *next;
}ArcNode;
typedef struct {  //表头 
    int vertex;         //存储图中结点数据
    ArcNode *firstEdge; //表头指针
}VertexNode[MAX];
class ALGraph{
    private:
        int vertexNum;      //结点数
        int arcNum;         //边数
        VertexNode adjList; //创建表头
    public:
        ALGraph(int v[],int n,int e);  //构造函数
        void display();
};
ALGraph::ALGraph(int v[],int n,int e){  //构造函数的实现,v[]是存储的数据
    vertexNum=n;      //结点数
    arcNum=e;         //边数
    for(int i=0;i<vertexNum;i++){   //表头数据初始化
        adjList[i].vertex=v[i];
        adjList[i].firstEdge=NULL;
    }
    int vi,vj;
    ArcNode *s;
    for(int i=0;i<arcNum;i++){
        cout<<"请输入第"<<i+1<<"条边的两个顶点在数组中的坐标"<<endl;
        cin>>vi>>vj;
        s=new ArcNode;
        s->adjvex=vj;
        s->next=adjList[vi].firstEdge;   //头插法
        adjList[vi].firstEdge=s;
    }
}
void ALGraph::display(){
    for(int i=0;i<vertexNum;i++){ 
        ArcNode *p=adjList[i].firstEdge;
        cout<<adjList[i].vertex;
        if(p) cout<<"->";
        while(p){
            cout<<p->adjvex<<" ";
            p=p->next;
            if(p) cout<<"->";
        } 
        cout<<endl;
    } 
}
int main(){
    int v[4]={0,1,2,3};
    ALGraph algraph(v,4,4);
    algraph.display();
    return 0;
}

输入:

0 1

0 2

2 3

3 0

输出:

0->2 ->1
1
2->3
3->0

 

十字链表

图的存储结构的比较———邻接矩阵和邻接表

发表评论

0/200
252 点赞
0 评论
收藏
为你推荐 换一批