本章介绍邻接表无向图。在"图的理论基础"中已经对图进行了理论介绍,这里就不再对图的概念进行重复说明了。和以往一样,本文会先给出C语言的实现;后续再分别给出C++和Java版本的实现。实现的语言虽不同,但是原理如出一辙,选择其中之一进行了解即可。若文章有错误或不足的地方,请不吝指出!

目录

1. 邻接表无向图的介绍
2. 邻接表无向图的代码说明
3. 邻接表无向图的完整源码

转载请注明出处:http://www.cnblogs.com/skywang12345/

更多内容:数据结构与算法系列 目录

邻接表无向图的介绍

邻接表无向图是指通过邻接表表示的无向图。

上面的图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()是读取用户的输入,将输入的数据转换成对应的无向图。

邻接表无向图的完整源码

点击查看:源代码

邻接表无向图(一)之 C语言详解的更多相关文章

  1. 邻接表有向图(一)之 C语言详解

    本章介绍邻接表有向图.在"图的理论基础"中已经对图进行了理论介绍,这里就不再对图的概念进行重复说明了.和以往一样,本文会先给出C语言的实现:后续再分别给出C++和Java版本的实现 ...

  2. 邻接矩阵无向图(一)之 C语言详解

    本章介绍邻接矩阵无向图.在"图的理论基础"中已经对图进行了理论介绍,这里就不再对图的概念进行重复说明了.和以往一样,本文会先给出C语言的实现:后续再分别给出C++和Java版本的实 ...

  3. 邻接表无向图(三)之 Java详解

    前面分别介绍了邻接表无向图的C和C++实现,本文通过Java实现邻接表无向图. 目录 1. 邻接表无向图的介绍 2. 邻接表无向图的代码说明 3. 邻接表无向图的完整源码 转载请注明出处:http:/ ...

  4. 邻接表无向图(二)之 C++详解

    本章是通过C++实现邻接表无向图. 目录 1. 邻接表无向图的介绍 2. 邻接表无向图的代码说明 3. 邻接表无向图的完整源码 转载请注明出处:http://www.cnblogs.com/skywa ...

  5. 原来Github上的README.md文件这么有意思——Markdown语言详解(sublime text2 版本)

    一直想学习 Markdown 语言,想起以前读的一篇 赵凯强 的 博客 <原来Github上的README.md文件这么有意思——Markdown语言详解>,该篇博主 使用的是Mac系统, ...

  6. 多表连接的三种方式详解 hash join、merge join、 nested loop

    在多表联合查询的时候,如果我们查看它的执行计划,就会发现里面有多表之间的连接方式.多表之间的连接有三种方式:Nested Loops,Hash Join 和 Sort Merge Join.具体适用哪 ...

  7. Python的Django框架中forms表单类的使用方法详解

    用户表单是Web端的一项基本功能,大而全的Django框架中自然带有现成的基础form对象,本文就Python的Django框架中forms表单类的使用方法详解. Form表单的功能 自动生成HTML ...

  8. 拓扑排序(一)之 C语言详解

    本章介绍图的拓扑排序.和以往一样,本文会先对拓扑排序的理论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 目录 1. 拓扑排序介绍 2. 拓扑排序的算法图解 3. 拓扑 ...

  9. Floyd算法(一)之 C语言详解

    本章介绍弗洛伊德算法.和以往一样,本文会先对弗洛伊德算法的理论论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 目录 1. 弗洛伊德算法介绍 2. 弗洛伊德算法图解 3 ...

随机推荐

  1. myeclipse导入项目出现乱码

    (1)修改整个工作空间的编码方式: Window->Preferences->General->Workspace->Text file Encoding 在 Others 里 ...

  2. WCF Failed to invoke the service. Possible causes: The service is offline or inaccessible

    今天写WCf 时遇到如下报错: 调试过程发现,各个过程都无异常,但是返回给调用端数据时出现如下错误. Failed to invoke the service. Possible causes: Th ...

  3. ORACLE 自定义分页存储过程

    一.创建包 CREATE OR REPLACE PACKAGE PKG_JK_LAB_BASIC IS TYPE CURSOR_TYPE IS REF CURSOR; PROCEDURE SP_GET ...

  4. Windows Phone 8.1 开发技术概览 (Universal APP)

    前一阵真的比较懒 WP8.1 已经出来这么长时间了现在才更新BLOG让大家久等了,今天我先为大家介绍下 WP 8.1的开发框架,什么是微软所推崇的 Universal APP,以及我们要开发 Univ ...

  5. [你必须知道的NOSQL系列]专题一:MongoDB快速入门

    一.前言 现在越来越多的公司开始采用非关系数据库了,并且很多公司的面试都要求面试者有MongoDB的使用经验,至于非关系数据库与关系型数据库之间的区别大家可以自行百度.但是作为程序员的我们,既然大部分 ...

  6. 让ZenCoding提升编码速度

    日前写了一篇关于VS神级插件Web Essentials的系列博客,其中在HTML&CSS操作技巧一节简单提到了ZenCoding,今天来详细说一下这个东西. 摘要 Zen Coding是一种 ...

  7. Linux修改环境变量的方法

    在Linux操作系统中,有时候跟着教程安装了一些软件,安装成功后,很高兴的准备运行该软件相应命令,但是偶尔会遇到”Command not found…“的提示.原因是因为你安装的软件需要设置环境变量才 ...

  8. Java设计模式12:装饰器模式

    装饰器模式 装饰器模式又称为包装(Wrapper)模式.装饰器模式以多客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式的结构 通常给对象添加功能,要么直接修改对象添加相应的功能, ...

  9. Java虚拟机2:Java内存区域及对象

    几个计算机的概念 为以后写文章考虑,也为巩固自己的知识和一些基本概念,这里要理清楚几个计算机中的概念. 1.计算机存储单位 从小到大依次为位Bit.字节Byte.千字节KB.兆M.千兆GB.TB,相邻 ...

  10. XP之后Windows的一些变化

    看到很多Windows开发人员,尤其是C++程序员思维还是停留在XP操作系统,当然根据工作是否需要新知识 ,这本身没有错.但是实际上Vista之后的Win7, 再之后的Win8 ,Windows已经发 ...