图的存储结构

目录

邻接矩阵

顶点存储:

边或弧存储:

邻接矩阵定义:

网:

 邻接矩阵存储的代码实现:

图的构造:

邻接表:

邻接表的处理方式如下:

逆邻接表:

 带权的网图:

邻接表实现代码:

结构实现:

邻接表创建(无向图):


邻接矩阵

考虑到图是由顶点和边或弧两部分组成,合在一起比较困难,那就自然想到分两个结构来分别存储。

顶点存储:

顶点不分大小、主次,所以用一个一维数组来存储是很不错的选择

边或弧存储:

边或弧由于是顶点与顶点之间的关系,一维搞不定,那就考虑二维数组来存储

邻接矩阵定义:

图的邻接矩阵存储方式是用两个数组来表示图。一个一维数组存储图中顶点信息,一个二维数组存储图中的边或弧的信息

网:

在图的术语中,我们提到了网的概念,也就是每条边上带有权的图叫做网。那么这些权值就需要存下来

 邻接矩阵存储的代码实现:

typedef char VertexType;//顶点类型应由用户定义
typedef int EdgeType;//边上的权值类型应由用户定义
#define MAXVEX 100//最大顶点树,应由用户定义
#define INFINITY 65535 //用65535来表示无穷

typedef struct {

VertexType vexs[MAXVEX];//顶点表
EdgeType arc[MAXVEX][MAXVEX];//邻接矩阵,可看做边边
int numNodes, numEdges;//图中当前的顶点数和边数

}MGraph;

图的构造:

代码实现:


void CreateMGraph(MGraph* G){
    int i,j,k,w;
    cout<<"输入顶点数和边数"<<end;
    scanf("%d %d",&G->numNodes,&G->numEdges);//输入顶点数和边数
    for(int i=0;i<G->numNodes;i++)//读入顶点信息,建立顶点表
    scanf("%d",&G->vex[i]);
    for(i=0;i<G->numNodes;i++){
        for(j=0;j<G->numEdges;j++){
            G->arc[i][j]=INFINITY;//邻接矩阵初始化
        }
    }
    for(k=0;k<G->numEdges;k++){
        cout<<"输入边上的下标i,下标j和权w"<<endl;
        cin>>i>>j>>w;
        G->arc[i][j]=w;
        G->arc[j][i]=G->arc[i][j];//无向图
    }
}

初始化的时间复杂度为O(N^2)

邻接表:

邻接矩阵是不错的一种图存储结构,但是我们也发现,对于边数相对顶点较少的图,这种结构是存在对存储空间的极大浪费的

 回忆我们在树中谈存储结构是,讲到了一种孩子表示法,将结点存入数组,并对结点的孩子进行粮食存储,不管有多少个孩子,也不会对空间造成浪费。

同样的思路适用于图的存储:

我们把这种数组与链表相结合的存储方法称为邻接表

邻接表的处理方式如下:

(1)图中顶点用一个一维数组存储,方便较容易读取顶点信息,同时每一个顶点还需要存储一个指向第一个临界点的指针

(2)图中每个顶点vi的所有邻接点构成一个线性表,由于邻接点的个数不定,所以用单链表存储,无向图称为顶点vi的边表,有向图称为顶点vi作为弧尾的出边表

 图中解析:

data:存储顶点的数据

firstedge:存储指向边表的第一个结点

adjvex:邻接点域,存储某顶点的邻接点在顶点表中的下标

next:存储指向边表下一个结点的指针

逆邻接表:

为了便于确定顶点的入读或以顶点为弧头的弧,我们可以建立一个有向图的逆邻接矩阵,即每个顶点vi都建立一个连接为vi为弧头的表。

 带权的网图:

我们可以在便捷点定义中再增加一个weight的数据域,存储权值信息即可

邻接表实现代码:

结构实现:

typedef char VertexType;
typedef int EdgeType;

typedef struct EdgeNode//边表结点
{
    int adjvex;//邻接点域,用于存储该顶点对应的下标
    EdgeType info;//用于网中存储权值
    struct EdgeNode *next;//链域,用于指向下一个邻接点
}EdgeNode;


typedef struct VertexNode//顶点表结点
{
    VertexType data;//顶点域,存储顶点信息
    EdgeNode *firstedge;//边表头指针
}VertexNode, AdjList[MAXVEX];


typedef struct
{
    AdjList adjList;
    int numNodes,numEdges;//图中当前顶点数和边数
}GraphAdjList;

邻接表创建(无向图):

void CreatALGraph(GraphAdjList *G)
{
    EdgeNode *e;
    cout<<"输入顶点数和边数"<<endl;
    cin>>G->numNodes>>G->numEdges;//输入顶点数和边数
    for(int i=0;i<G->numNodes;i++)//读入顶点信息,建立顶点表
    {
        cin>>G->adjList[i].data;//输入顶点信息
        G->adjList[i].firstedge=NULL;//将边表置为空表
    }
    

    for(int k=0;k<G->numEdges;k++)//建立边表
    {
        cout<<"输入边上的顶点序号"<<endl;
        cin>>i>>j;
        e=(EdgeNode*)malloc(sizeof(EdgeNode));//向内存申请空间,生成边表结点
        e->adjvex=j;//邻接序号为j
        e->next=G->adjList[i].firstedge;//将e的指针指向当前顶点指向的结点
        G->adjList[i].fristedge=e;
        e=(EdgeNode*)malloc(sizeof(EdgeNode));
        e->adjvex=i;//邻接序号为i
        e->next=G->adjList[j].firstedge;
        G->adjList[j].fristedge=e;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值