邻接表无向图的介绍
邻接表无向图是指通过邻接表表示的无向图。
上面的图G1包含了"A,B,C,D,E,F,G"共7个顶点,而且包含了"(A,C),(A,D),(A,F),(B,C),(C,D),(E,G),(F,G)"共7条边。
上图右边的矩阵是G1在内存中的邻接表示意图。每一个顶点都包含一条链表,该链表记录了"该顶点的邻接点的序号"。例如,第2个顶点(顶点C)包含的链表所包含的节点的数据分别是"0,1,3";而这"0,1,3"分别对应"A,B,D"的序号,"A,B,D"都是C的邻接点。就是通过这种方式记录图的信息的。
邻接表无向图的代码说明
1. 基本定义
// 邻接表中表对应的链表的顶点
typedef struct _ENode
{
int ivex; // 该边所指向的顶点的位置
struct _ENode *next_edge; // 指向下一条弧的指针
}ENode, *PENode;
// 邻接表中表的顶点
typedef struct _VNode
{
char data; // 顶点信息
ENode *first_edge; // 指向第一条依附该顶点的弧
}VNode;
// 邻接表
typedef struct _LGraph
{
int vexnum; // 图的顶点的数目
int edgnum; // 图的边的数目
VNode vexs[MAX];
}LGraph;
(01) LGraph是邻接表对应的结构体。
vexnum是顶点数,edgnum是边数;vexs则是保存顶点信息的一维数组。
(02) VNode是邻接表顶点对应的结构体。
data是顶点所包含的数据,而first_edge是该顶点所包含链表的表头指针。
(03) ENode是邻接表顶点所包含的链表的节点对应的结构体。
ivex是该节点所对应的顶点在vexs中的索引,而next_edge是指向下一个节点的。
2. 创建矩阵
这里介绍提供了两个创建矩阵的方法。一个是用已知数据,另一个则需要用户手动输入数据。
2.1 创建图(用已提供的矩阵)
/*
* 创建邻接表对应的图(用已提供的数据)
*/
LGraph* create_example_lgraph()
{
char c1, c2;
char vexs[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
char edges[][2] = {
{'A', 'C'},
{'A', 'D'},
{'A', 'F'},
{'B', 'C'},
{'C', 'D'},
{'E', 'G'},
{'F', 'G'}};
int vlen = LENGTH(vexs);
int elen = LENGTH(edges);
int i, p1, p2;
ENode *node1, *node2;
LGraph* pG;
if ((pG=(LGraph*)malloc(sizeof(LGraph))) == NULL )
return NULL;
memset(pG, 0, sizeof(LGraph));
// 初始化"顶点数"和"边数"
pG->vexnum = vlen;
pG->edgnum = elen;
// 初始化"邻接表"的顶点
for(i=0; i<pG->vexnum; i++)
{
pG->vexs[i].data = vexs[i];
pG->vexs[i].first_edge = NULL;
}
// 初始化"邻接表"的边
for(i=0; i<pG->vexnum; i++)
{
// 读取边的起始顶点和结束顶点
c1 = edges[i][0];
c2 = edges[i][1];
p1 = get_position(*pG, c1);
p2 = get_position(*pG, c2);
// 初始化node1
node1 = (ENode*)malloc(sizeof(ENode));
node1->ivex = p2;
// 将node1链接到"p1所在链表的末尾"
if(pG->vexs[p1].first_edge == NULL)
pG->vexs[p1].first_edge = node1;
else
link_last(pG->vexs[p1].first_edge, node1);
// 初始化node2
node2 = (ENode*)malloc(sizeof(ENode));
node2->ivex = p1;
// 将node2链接到"p2所在链表的末尾"
if(pG->vexs[p2].first_edge == NULL)
pG->vexs[p2].first_edge = node2;
else
link_last(pG->vexs[p2].first_edge, node2);
}
return pG;
}
createexamplelgraph()的作用是创建一个邻接表无向图。实际上,该方法创建的无向图,就是上面图G1。
2.2 创建图(自己输入)
/*
* 创建邻接表对应的图(自己输入)
*/
LGraph* create_lgraph()
{
char c1, c2;
int v, e;
int i, p1, p2;
ENode *node1, *node2;
LGraph* pG;
// 输入"顶点数"和"边数"
printf("input vertex number: ");
scanf("%d", &v);
printf("input edge number: ");
scanf("%d", &e);
if ( v < 1 || e < 1 || (e > (v * (v-1))))
{
printf("input error: invalid parameters!\n");
return NULL;
}
if ((pG=(LGraph*)malloc(sizeof(LGraph))) == NULL )
return NULL;
memset(pG, 0, sizeof(LGraph));
// 初始化"顶点数"和"边数"
pG->vexnum = v;
pG->edgnum = e;
// 初始化"邻接表"的顶点
for(i=0; i<pG->vexnum; i++)
{
printf("vertex(%d): ", i);
pG->vexs[i].data = read_char();
pG->vexs[i].first_edge = NULL;
}
// 初始化"邻接表"的边
for(i=0; i<pG->vexnum; i++)
{
// 读取边的起始顶点和结束顶点
printf("edge(%d): ", i);
c1 = read_char();
c2 = read_char();
p1 = get_position(*pG, c1);
p2 = get_position(*pG, c2);
// 初始化node1
node1 = (ENode*)malloc(sizeof(ENode));
node1->ivex = p2;
// 将node1链接到"p1所在链表的末尾"
if(pG->vexs[p1].first_edge == NULL)
pG->vexs[p1].first_edge = node1;
else
link_last(pG->vexs[p1].first_edge, node1);
// 初始化node2
node2 = (ENode*)malloc(sizeof(ENode));
node2->ivex = p1;
// 将node2链接到"p2所在链表的末尾"
if(pG->vexs[p2].first_edge == NULL)
pG->vexs[p2].first_edge = node2;
else
link_last(pG->vexs[p2].first_edge, node2);
}
return pG;
}
create_lgraph()是读取用户的输入,将输入的数据转换成对应的无向图。
源码:
https://github.com/wangkuiwu/datastructs_and_algorithm/blob/master/source/graph/basic/udg/c/list_udg.c
http://www.cnblogs.com/skywang12345/p/3707607.html
相关推荐
数据结构 - 图的存储结构 - 邻接表的创建 - 无向图。 在数据结构中,图是一种非常重要的数据结构,它广泛应用于计算机科学和信息技术领域中。在本节中,我们将讨论图的存储结构,并使用 C 语言实现图的邻接表的创建...
对于无向图,每条边在两个顶点的邻接列表中各出现一次;对于有向图,边只在一个顶点的邻接列表中出现。 接下来,我们将学习如何用C语言实现邻接表: 1. **顶点结构**:首先,我们需要定义一个结构体表示顶点,可能...
在本文中,我们将深入探讨如何使用C语言实现无向图的广度优先搜索(BFS)遍历,其中涉及到了数据结构如邻接表、队列,并使用了CFree软件进行辅助开发。首先,让我们详细了解这些概念。 **数据结构:邻接表** 邻接表...
为了有效地存储和处理图结构,我们通常采用多种存储方式,其中邻接表是用于无向图和有向图的一种高效存储方法。 #### 邻接表的定义与特性 邻接表通过将每个顶点关联到一个链表来存储图,这个链表包含了与该顶点...
数据结构-c语言-图的存储结构-图的邻接矩阵的创建-无向图 数据结构是计算机科学中最重要的概念之一,它是指计算机中组织、存储和管理数据的方式。图是一种常见的数据结构,代表着顶点和边之间的关系。图的存储结构...
在C语言中实现无向图的邻接表,首先需要定义数据结构来表示顶点和边。一般可以定义一个结构体,如`Vertex`表示顶点,包含顶点的标识(如编号或名称);另一个结构体`Edge`表示边,包含两个顶点的引用。然后,为每个...
对于无向图,邻接矩阵是对称的,因为每条边连接两个节点,所以A[i][j]等于A[j][i]。而对于有向图,这个性质可能不成立。 在程序的开始,用户会被要求输入图的节点数和边数。节点数表示图中顶点的数量,而边数则表示...
### 建立一个带权无向图用邻接矩阵表示,判断此图是否连通 在本篇文章中,我们将探讨如何使用邻接矩阵来表示一个带权无向图,并进一步判断该图是否连通。如果图是连通的,则会使用Prim算法找到该图的最小生成树。 ...
### 无向图的邻接矩阵存储及输出详解 在计算机科学中,图是一种重要的数据结构,用于表示对象之间的关系。图由顶点(或节点)和边组成,其中边可以是有向的或无向的。本文将详细介绍无向图的邻接矩阵存储方式以及...
对于无向图,两个顶点如果互相邻接,它们在对方的邻接表中都会出现。对于有向图,只有起点会在终点的邻接表中出现。 3. **C语言基础**: - **变量声明**:在C语言中,我们需要先声明变量类型,然后给变量命名。...
对于无向图,邻接矩阵是对称的;而对于有向图,则不一定对称。 - **无向图**:如果顶点i与顶点j之间存在边,则邻接矩阵中对应位置的元素为1,否则为0。 - **有向图**:如果从顶点i指向顶点j存在一条边,则邻接矩阵...
用邻接表实现无向图的存储结构,并进行深度优先搜索及广度优先搜索。
邻接表是用于表示无向图或有向图的一种数据结构,其中每个顶点都有一个链表,链表中的元素代表与该顶点相邻的其他顶点。对于无向图,如果顶点A与顶点B相连,那么A的链表中会有B,反之亦然。对于有向图,A的链表中...
综上所述,用C语言实现无向图的算法时,需要掌握图的逻辑结构、存储结构(邻接矩阵和邻接表)、遍历算法(DFS和BFS)、最小生成树算法、最短路径算法以及拓扑排序等核心知识。在实际编程中,根据图的特性选择合适的...
对于一个无向图或有向图,邻接表通过一系列链表来表示图中的顶点及其连接的边。每个顶点都对应着一个链表,链表中的节点(称为边节点)存储了与该顶点相连的所有邻接顶点的信息。这种方式特别适用于稀疏图(即边的...
本文档旨在深入探讨无向图的邻接多重表存储表示和实现,并使用C语言这一强大的编程工具来完整地展开这一主题。在阅读本文后,读者将能够理解无向图的邻接多重表的存储结构,并掌握其基本操作的C语言实现方法。 首先...
例如,如果我们要添加边(u, v),则将v插入到u的链表中,同时也要将u插入到v的链表中,以保持无向图的对称性。 3. **删除边**: - 删除边的操作与增加边类似,但需要从两个节点的邻接表中移除相应的节点。对于边(u,...
6. **计算连通分量**:对于无向图,找出图中的所有连通分量。可以使用DFS进行标记,记录每个连通分量中的顶点。 以下是一些基本操作的C语言实现示例: ```c // 创建新顶点 Vertex* createVertex(int id) { Vertex...
### C语言实现无向图的深度优先遍历 #### 一、无向图与深度优先遍历概述 在计算机科学中,无向图是一种数据结构,由一系列节点(顶点)以及连接这些节点的边组成。如果边没有方向性,则称这样的图为无向图。在图论...
邻接多重表是一种用于存储无向图的数据结构,它通过在每个顶点处维护一个指向与之相连的所有边的链表来表示图。这种数据结构不仅可以高效地存储图数据,而且可以方便地进行图的遍历操作,如深度优先搜索(DFS)和...