图的存储结构你了解多少

前言

这是我听老师讲课做的笔记,考试要看的。
作者:RodmaChen
关注我的csdn博客,更多数据结构与算法知识还在更新

一.邻接矩阵

1.邻接矩阵表示法

(1)基本思想

一维数组存储图的顶点,用矩阵 n*n(二维数组)表示图中各顶点之间的邻接关系。有边指向顶点就用1表示,没有就用0。

行的1相加就是度

行是出度,列是入度,加起来就是度
在这里插入图片描述

如果有相连就用权值,没有就用表示

优点:很容易确定两点之间是否有边相连

缺点:浪费存储空间,无法确定有多少条边

2.邻接矩阵算法建立

typedef struct
{
VertexType vexs[MAXSIZE];  /*顶点表*/
EdeType edges[MAXSIZE][MAXSIZE];  /*邻接矩阵,即边表*/
int n,e; /*顶点数和边数*/
}MGraph; /*MGragh是以邻接矩阵存储的图类型*/
访问形式:Mgraph gh;
gh.vexs; //存放顶点信息
gh.edges;//存放关系

建立无向图的邻接矩阵表示

void CreateMGraph(Mgraph *G)
{ int i,j,k;
scanf(%d%d”,&G->n,&->e);//输入顶点数和边数
for(i=0;i<G->n;i++)
scanf(“\n%c”,&(G->vexs[i]));//输入顶点信息
for(i=0;i<G->n;i++)
for(j=0; j<G->n;j++)
G->edges[i][j]=0; //邻接矩阵初始化
for(k=0; k<G->e;k++)
{ scanf("\n%d,%d",&i,&j); //输入e条边,建立邻接矩阵
G->edges[i][j]=1;
G->edges[j][i]=1; }
}

建立有向图的邻接矩阵表示

void CreateMGraph(Mgraph *G)
{ int i,j,k;
scanf(%d%d”,&G->n,&->e);//输入顶点数和边数
for(i=0;i<G->n;i++)
scanf(“\n%c”,&(G->vexs[i]));//输入顶点信息
for(i=0;I<G->n;i++)
for(j=0; j<G->n;j++)
G->edges[i][j]=0; //邻接矩阵初始化
for(k=0; k<G->e;k++)
{ scanf("\n%d,%d",&i,&j); //输入e条边,建立邻接矩阵
G->edges[i][j]=1;
}
}

二.邻接表

1.邻接表表示法

基本思想

在这里插入图片描述
为什么 v 2 v_2 v2 v 4 v_4 v4前面,因为采用头插法,每次插到头结点后边

由图可知:顶点 V i V_i Vi的度为第i条链表中的结点数,需要的存储空间为n+2e(n是结点,2e可以看成是边)
在这里插入图片描述

与无向图不同,只看射出去的边

由图可知:顶点vi的出度为第i条链表中的结点数,需要的存储空间为n+e

为了求入度,加入逆接表,存储空间为2n+2e

2.图的邻接表的建立

Typedef struct VNode{ //顶点结构
VertexType data; //顶点信息
EdgeNode * firstarc; //指向依附该顶点的第一条弧的指针
} VertexNode; /*表头结点*/
Typedef struct Node {
int adjvex; //该弧所指向的顶点位置
struct Node *next; //指向下一条弧的指针
}EdgeNode;/*边结点*/
Typedef struct { //图结构
VertexNode adjList[100] ; //应包含邻接表,头结点类型
int n,e //应包含顶点总数和弧总数
} ALGraph; //图结构,看到ALG就说明用连接表表示的,看到MG说明用连接矩阵表示的

建立一个有向图的邻接表存储的算法如下:

(1)读入顶点边数

(2)一维数组初始化

(3)挂节点:单链表头插法

void CreateALGraph(ALGraph *G)
{ int i,j,k;
EdgeNode * s;//边结点
scanf("%d,%d",&(G->n),&(G->e)); /*读入顶点数和边数*/
for (i=0;i<G->n;i++) /*建立有n个顶点的顶点表*/
{ scanf("\n%c",&(G->adjlist[i].vertex)); /*读入顶点信息*/
G->adjlist[i].firstedge=NULL; } /*顶点的边表头指针设为空,初始化*/
for (k=0;k<G->e;k++) /*建立边表*/
{ scanf("\n%d,%d",&i,&j); /*读入边<Vi,Vj>的顶点对应序号*/
s=(EdgeNode*)malloc(sizeof(EdgeNode)); /*生成新边表结点s*/
s->adjvex=j; /*邻接点序号为j*/
s->next=G->adjlist[i].firstedge;//甩尾巴
G->adjlist[i].firstedge=s;//拉绳子 }
}/*CreateALGraph*/]

建立一个无向图的邻接表存储的算法如下:

(4)由于无向图没有箭头,所以最后重复,i挂j,j挂i

void GreateALGraph(ALGraph *G)
{ int i,j,k; EdgeNode *s;
Scanf(%d%d”,&G->n,&->e); //读入顶点数和边数
for(i=0;i<G->n;i++)//建立顶点表
{ G->adjlist[i].vertex=getchar(); //读入顶点信息
G->adjlist[i].firstedge=NULL; } //边表置为空表
for(k=0;k<G->e;k++)//建立边表
{ scanf(%d%d”,&i,&j); //读入边(Vi,Vj)的顶点对序号
s=(EdgeNode *)malloc(sizeof(EdgeNode)); //生成边表结点
s->adjvex=j;
s->next=G->adjlist[i].firstedge;
G->adjlist[i].firstedge=s;//将新结点*s插入顶点Vi的边表头部
s=(EdgeNode *)malloc(sizeof(EdgeNode));
s->adjvex=i;//邻接点序号为i
s->next=G->adjlist[j].firstedge;
G->adjlist[j].firstedge=s; // 将新结点*s插入顶点Vj的边表头部}
}

三.边学边练

1、下列关于无向连通图特性的叙述中,正确的是(A)

I.所有顶点的度之和为偶数(所有顶点度之和等于边的两倍)

Ⅱ.边数大于顶点个数减1(生成树边数等于于顶点个数减1)

Ⅲ.至少有一个顶点的度为1(完全图)

A. 只有Ⅰ B. 只有Ⅱ C.Ⅰ和Ⅱ D.Ⅰ和Ⅲ

2、若无向图G=(V,E)中含7个顶点,则保证图G在任何
情况下都是连通的,则需要的边数最少是(c)

A、6

B、15

C、16

D、21

无向完全图:边数=n*(n-1)/2

可以先将六个顶点搭成无向完全图,在用一个顶点连接

3、请画出下面无向图的邻接矩阵和邻接表。
在这里插入图片描述
答案:

本人博客:https://blog.csdn.net/weixin_46654114
本人b站求关注:https://space.bilibili.com/391105864
转载说明:跟我说明,务必注明来源,附带本人博客连接。

请给我点个赞鼓励我吧
在这里插入图片描述

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 博客之星2020 设计师:CY__0809 返回首页