目录

  • 1. 邻接矩阵表示法
    • 1.1 图的邻接矩阵
    • 1.2 创建有向网的邻接矩阵
  • 2. 邻接表表示法
    • 2.1 图的邻接表存储结构
    • 2.2 创建有向图的邻接表
  • 3. 十字链表表示法
    • 3.1 图的十字链表存储结构
    • 3.2 创建有向图的十字链表
  • 4. 邻接多重表
    • 4.1 邻接多重表的存储结构
    • 4.2 创建无向图的邻接多重表

1. 邻接矩阵表示法

1.1 图的邻接矩阵

图的邻接矩阵表示法(Adjacency Matrix)也称作数组表示法。它采用两个数组来表示图:一个是用于存储顶点信息的一维数组,另一个是用于存储图中顶点之间关联关系的二维数组,这个关联关系数组被称为邻接矩阵
有向图的邻接矩阵可以指示弧的方向;无向图的邻接矩阵没有方向,所以是对称矩阵;
稀疏图不适于用邻接矩阵来存储,会造成空间浪费。

1.2 创建有向网的邻接矩阵

# include<stdio.h>
# define MAX_VERTEX_NUM 20          //最多顶点个数
# define INFINITY 32768             //表示极大值,即∞/*图的邻接矩阵表示法*/
typedef int AdjType;
typedef char VertexData;
typedef struct ArcNode {AdjType adj;                            //无权图用1或0表示是否相邻,带权图则为权值类型
}ArcNode;
typedef struct {VertexData vertex[MAX_VERTEX_NUM];      //顶点向量ArcNode arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//邻接矩阵int vexnum, arcnum;                        //图的顶点数和弧数
}AdjMatrix;/*采用邻接矩阵表示法创建有向网*/
/*求顶点位置*/
int LocateVertex(AdjMatrix* G, VertexData v) {int k;for (k = 0; k < G->vexnum; k++) {if (G->vertex[k] == v)break;}return k;
}/*创建有向网*/
int CreateDN(AdjMatrix* G) {int i, j, k, weight;VertexData v1, v2;printf("输入图的顶点数和弧数:");           //输入图的顶点数和弧数scanf("%d%d", &G->vexnum, &G->arcnum);for (i = 0; i < G->vexnum; i++) {        //初始化邻接矩阵for (j = 0; j < G->vexnum; j++)G->arcs[i][j].adj = INFINITY;}printf("输入图的顶点:");for (i = 0; i < G->vexnum; i++)          //输入图的顶点scanf(" %c", &G->vertex[i]);for (k = 0; k < G->arcnum; k++) {printf("输入第%d条弧的两个顶点及权值:", k + 1);scanf(" %c %c %d", &v1, &v2, &weight); //输入一条弧的两个顶点及权值i = LocateVertex(G, v1);j = LocateVertex(G, v2);G->arcs[i][j].adj = weight;            //建立弧}
}/*邻接矩阵的输出*/
void AdjMatrixDisplay(AdjMatrix* G) {printf("图的邻接矩阵输出:\n");int i, j;for (i = 0; i < G->vexnum; i++) {printf("\t%c", G->vertex[i]);}printf("\n");for (i = 0; i < G->vexnum; i++) {     //输出邻接矩阵printf("%c\t", G->vertex[i]);for (j = 0; j < G->vexnum; j++) {if (G->arcs[i][j].adj == INFINITY)printf("∞\t");elseprintf("%d\t", G->arcs[i][j].adj);}printf("\n");}
}int main() {AdjMatrix G;CreateDN(&G);AdjMatrixDisplay(&G);return 0;
}

运行结果

2. 邻接表表示法

2.1 图的邻接表存储结构

邻接表(Adjacency List)表示法是图的一种链式存储结构,它只存储图中存在的边信息。在邻接表中,对图中的每一个顶点建立一个带头结点的边链表,每个边链表的头结点又构成一个表头结点表。这样,一个n个顶点的图的邻接表表示由表头结点与边表两部分构成。
表头结点表:由所有表头结点以顺序结构(向量)的形式存储,以便可以随机访问任一顶点的边链表。表头结点由两部分组成,其中数据域vexdata用于存储顶点的名或其它相关信息;链域firstarc用于指向链表中第一个顶点。
边表:由表示图中顶点间邻接关系的n个边链表组成。边链表的弧结点结构由三部分组成,邻接点域adjvex用于存放与顶点vi相邻接的顶点在图中的位置;链域nextarc用于指向与顶点vi相关联的下一条边或弧的结点;数据域info用于存放与边或弧相关的信息(如赋权图中每条边或弧的权值)。

# define MAX_VERTEX_NUM 20                   //最多顶点个数/*图的邻接表表示法*/
typedef char VertexData;
//弧结点结构
typedef struct ArcNode {int adjvex;                             //该弧指向顶点的位置struct ArcNode* nextarc;             //指向下一条弧的指针int info;                                //与弧相关的信息
}ArcNode;
//表头结点结构
typedef struct VertexNode {VertexData data;                     //顶点数据ArcNode* firstarc;                        //指向该顶点的第一条弧的指针
}VertexNode;
//邻接表结构
typedef struct {VertexNode vertex[MAX_VERTEX_NUM];int vexnum, arcnum;                       //图的顶点数和弧数
}AdjList;

2.2 创建有向图的邻接表

/*采用邻接表表示法创建有向图*/
/*求顶点位置*/
int LocateVertex(AdjList* G, VertexData v) {int k;for (k = 0; k < G->vexnum; k++) {if (G->vertex[k].data == v)break;}return k;
}/*创建有向图*/
int CreateAdjList(AdjList* G) {int i, j, k;VertexData v1, v2;ArcNode* p;printf("输入图的顶点数和弧数:");         //输入图的顶点数和弧数scanf("%d%d", &G->vexnum, &G->arcnum);printf("输入图的顶点:");for (i = 0; i < G->vexnum; i++) {     //输入图的顶点,初始化顶点结点scanf(" %c", &(G->vertex[i].data));G->vertex[i].firstarc = NULL;}for (k = 0; k < G->arcnum; k++) {printf("输入第%d条弧的两个顶点:", k + 1);scanf(" %c %c", &v1, &v2);            //输入一条弧的两个顶点i = LocateVertex(G, v1);j = LocateVertex(G, v2);p = (ArcNode*)malloc(sizeof(ArcNode));   //申请新弧结点p->adjvex = j;p->nextarc = G->vertex[i].firstarc;G->vertex[i].firstarc = p;}
}

3. 十字链表表示法

3.1 图的十字链表存储结构

十字链表(Orthogonal List)是有向图的另一种链式存储结构。有向图中的每一条弧对应十字链表中的一个弧结点,同时有向图中的每个顶点在十字链表中对应有一个结点,称为顶点结点。

data:用于存储与顶点有关的信息,如顶点的名字等。
firstin:用于指向以该顶点作为弧头的第一个弧顶点。
firstout:用于指向以该顶点作为弧尾的第一个弧顶点。

tailvex:表示弧尾顶点在图中的位置。
headvex:表示弧头顶点在图中的位置。
hlink:指向与此弧的弧头相同的下一条弧。
tlink:指向与此弧的弧尾相同的下一条弧。
info:指向该弧的相关信息,如权值等。

# define MAX_VERTEX_NUM 20                   //最多顶点个数/*十字链表表示法*/
typedef char VertexData;
//弧结点结构
typedef struct ArcNode {int tailvex, headvex;struct ArcNode* hlink, * tlink;
}ArcNode;
//顶点结构
typedef struct VertexNode {VertexData data;                     //顶点信息ArcNode* firstin, * firstout;
}VertexNode;
//十字链表结构
typedef struct {VertexNode vertex[MAX_VERTEX_NUM];int vexnum, arcnum;                       //图的顶点数和弧数
}OrthList;

3.2 创建有向图的十字链表

/*创建有向图的十字链表*/
/*求顶点位置*/
int LocateVertex(OrthList* G, VertexData v) {int k;for (k = 0; k < G->vexnum; k++) {if (G->vertex[k].data == v)break;}return k;
}/*创建有向图的十字链表*/
void CreateOrthList(OrthList* G) {int i, j, k;VertexData vt, vh;ArcNode* p;printf("输入图的顶点数和弧数:");scanf("%d%d", &G->vexnum, &G->arcnum);    //输入图的顶点数和弧数printf("输入图的顶点:");for (i = 0; i < G->vexnum; i++) {       //输入图的顶点,初始化顶点结点scanf(" %c", &(G->vertex[i].data));G->vertex[i].firstin = NULL;G->vertex[i].firstout = NULL;}for (k = 0; k < G->arcnum; k++) {printf("输入第%d条弧的弧尾和弧头:", k + 1);scanf(" %c %c", &vt, &vh);i = LocateVertex(G, vt);j = LocateVertex(G, vh);p = (ArcNode*)malloc(sizeof(ArcNode));  //申请新弧结点p->tailvex = i;p->headvex = j;p->tlink = G->vertex[i].firstout;G->vertex[i].firstout = p;p->hlink = G->vertex[j].firstin;G->vertex[j].firstin = p;}
}

4. 邻接多重表

4.1 邻接多重表的存储结构

邻接多重表(Adjacency Multi-list)是无向图的存储结构,它能够提供更为方便的边处理信息。
data:用于存储与顶点有关的信息,如顶点的名字。
firstedge:用于指向第一条依附于该顶点的边。
mark:标志域,用以标记该条边是否被搜索过。
ivex / jvex:为该边依附的两个顶点在图中的位置。
ilink:用于指向下一条依附于顶点ivex的边。
jlink:用于指向下一条依附于顶点jvex的边。

# define MAX_VERTEX_NUM 20                   //最多顶点个数/*邻接多重表表示法*/
typedef char VertexData;
//边结点结构
typedef struct EdgeNode {int mark, ivex, jvex;struct EdgeNode* ilink, * jlink;
}EdgeNode;
//顶点结点结构
typedef struct {VertexData data;EdgeNode* firstedge;
}VertexNode;
//邻接多重表结构
typedef struct {VertexNode vertex[MAX_VERTEX_NUM];int vexnum, arcnum;                       //图的顶点数和弧数
}AdjMultiList;

4.2 创建无向图的邻接多重表

/*创建无向图的邻接多重表*/
/*求顶点位置*/
int LocateVertex(AdjMultiList* G, VertexData v) {int k;for (k = 0; k < G->vexnum; k++) {if (G->vertex[k].data == v)break;}return k;
}/*创建无向图的邻接多重表*/
void CreateAdjMultiList(AdjMultiList* G) {int i, j, k;VertexData v1, v2;EdgeNode* p;printf("输入图的顶点数和弧数:");scanf("%d%d", &G->vexnum, &G->arcnum);   //输入图的顶点数和弧数printf("输入图的顶点:");for (i = 0; i < G->vexnum; i++) {       //输入图的顶点,初始化顶点结点scanf(" %c", &(G->vertex[i].data));G->vertex[i].firstedge = NULL;}for (k = 0; k < G->arcnum; k++) {printf("输入第%d条弧的两个顶点:", k + 1);scanf(" %c %c", &v1, &v2);           //输入一条弧的两个顶点i = LocateVertex(G, v1);j = LocateVertex(G, v2);p = (EdgeNode*)malloc(sizeof(EdgeNode));p->ivex = i;p->jvex = j;p->mark = 0;p->ilink = G->vertex[i].firstedge;p->jlink = G->vertex[j].firstedge;G->vertex[i].firstedge = p;G->vertex[j].firstedge = p;}
}

参考:耿国华《数据结构——用C语言描述(第二版)》

更多数据结构内容关注我的《数据结构》专栏:https://blog.csdn.net/weixin_51450101/category_11514538.html?spm=1001.2014.3001.5482

【数据结构】图的存储结构(邻接矩阵、邻接表、十字链表、邻接多重表)及实现(C语言)相关推荐

  1. 20.0、C语言数据结构——图的存储结构

    20.0.C语言数据结构--图的存储结构 图的存储结构相比较线性表与树来说就复杂很多了: 1. 我们回顾下,对于线性表来说,是一对一的关系,所以用数组或者链表均可简单存放:树结构是一对多的关系,所以我 ...

  2. 数据结构考研笔记(十五)——图的存储结构邻接矩阵、邻接表、十字链表、临界多重表的概念

    图的存储结构 1.邻接矩阵 1.1有向图 1.2无向图 2.邻接表法 2.1有向图边表 2.2无向图边表 3.十字链表 4.临界多重表 十字链表与临界多重表 1.邻接矩阵 邻接矩阵法结点数为n的图G ...

  3. 数据结构——图(存储结构)

    数据结构--图 图的定义和基本术语 图的类型定义 图的存储结构 数组(邻接矩阵表示法) 网(即有权图)的邻接矩阵表示法 邻接表 邻接表表示法(链式) 图的邻接表存储表示 采用邻接表表示法创建无向网 邻 ...

  4. 数据结构--图的存储结构

    系列文章目录 第九话  数据结构之图的存储 文章目录 一.了解什么是图 二.图的定义和基本术语 三.存储结构之邻接矩阵 1.邻接矩阵的介绍 2.邻接矩阵的创建 3.主函数中实现 四.存储结构之邻接表 ...

  5. 数据结构——图的存储结构

    邻接矩阵法 通过矩阵来表示所有的 有向图的邻接矩阵法 无向图的邻接矩阵法 无向图的矩阵一定是对称的,可以才用压缩存储方式 网的邻接矩阵法 网就是带权值的图,所以数组里面直接放权值,不存在的边用正无穷表 ...

  6. 7.2图的存储结构(邻接矩阵)

    邻接矩阵(无向图) 因为图是由顶点和边或弧组成的,所以最好是把他们分开存储. 下面来看无向图的邻接矩阵. 图的邻接矩阵(Adjacency Matrix)存储方式是用两个数组来表示图. 如下图所示: ...

  7. 图的存储结构(邻接矩阵和邻接表)

    图的存储结构(邻接矩阵和邻接表) 前言: 前面我们学习图的有些定义和术语,对图这个数据结构有了新的见解和认知,让我们理解图结构的知识,今天我们学习图的存储结构,图的存储结构比较多,我们今天主要是学习邻 ...

  8. 数据结构之图的存储结构:邻接多重表

    图的存储结构:邻接多重表 产生条件: 邻接多重表的定义: 邻接多重表的代码定义: 删除: 性能分析: 十字链表与邻接多重表的对比 产生条件: 当用邻接矩阵法存储时:空间复杂度为O(|V|^2),太大 ...

  9. 数据结构之图的存储结构:邻接表法

    图的存储结构:邻接表法 产生条件: 邻接表法的定义: 邻接表法的特点: 邻接表法的代码定义: 邻接表法与邻接矩阵法的对比: 产生条件: 当用邻接矩阵存储时:空间复杂度为O(|v|^2),太大 邻接表法 ...

最新文章

  1. Spring Boot 的 10 个核心模块
  2. 树莓派安装Ubuntu
  3. 删除联想OEM分区的方法 推荐!
  4. Codeforces Gym 100650B Countdown (离线)
  5. [转]九个Console命令,让js调试更简单
  6. java xfire下载_XFIRE教程 PDF 下载
  7. React应用里Invalid hook call错误消息的处理
  8. Generator函数的基本概念
  9. POI报表入门,excel,使用事件模型解析百万数据excel报表
  10. linux服务器安装nexus,Linux下搭建maven服务器nexus
  11. mysql让数据-1_mysql数据库基本操作1
  12. FPGA之旅设计99例之第十八例----OV5640摄像头SCCB时序
  13. linux用光盘安装系统时需要如何设置,Linux如何设置光盘启动
  14. The destination is read-only
  15. Linux模拟试题及答案(全)
  16. linux查看系统所有变量,Linux系统各指标命令
  17. RGB转YUV420,支持NV12(420p)和NV21(420sp)
  18. 蓝桥杯学习记录-基础练习
  19. 优步UBER司机全国各地奖励政策汇总 (4月4日-4月10日)
  20. shell中for循环

热门文章

  1. KB5022282 0x800F0922 安装更新失败
  2. Perceptron感知机代码讲解笔记
  3. 面试时巧用这些“谈薪技巧”,让你的薪资提高20%!
  4. 2021上海复旦微电子IC
  5. 在VS中使用万能头文件#include bits/stdc++.h编译错误的解决方法
  6. “魔幻”的直播带货:一夜血亏100万,依然有无数人入局!
  7. Android视频播放器缓冲时流量显示的实现方式
  8. 腾讯音乐财报:年营收超300亿 拟在香港以介绍形式二次上市
  9. 关于微前端,你想知道的都在这!
  10. 用数据说话,外贸B2C产品选择(上篇)-热门搜索法