数据结构之图的创建(邻接表)
数据结构之图的基本概念中了解了图的基本概念,接下来对图的代码实现进行详解。
邻接无向图
1. 邻接表无向图介绍
邻接表无向图是指通过邻接表表示的无向图。
上面的图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的邻接点。就是通过这种方式记录图的信息的。
2. 邻接表无向图代码实现
(1)数据结构
struct ENode {int nVindex; // 该边所指的顶点的位置ENode *pNext; // 指向下一个边的指针 };struct VNode {char data; // 顶点信息ENode *pFirstEdge; // 指向第一条依附该顶点的边 };
(2)图的创建
listUDG(char *vexs, int vlen, char edges[][2], int elen) {m_nVexNum = vlen;m_nEdgNum = elen;// 初始化"邻接表"的顶点for (int i = 0; i < vlen; i ++){m_mVexs[i].data = vexs[i];m_mVexs[i].pFirstEdge = NULL;}char c1,c2;int p1,p2;ENode *node1, *node2;// 初始化"邻接表"的边for (int j = 0; j < elen; j ++){// 读取边的起始顶点和结束顶点c1 = edges[j][0];c2 = edges[j][1];p1 = GetVIndex(c1);p2 = GetVIndex(c2);node1 = new ENode();node1->nVindex = p2;if (m_mVexs[p1].pFirstEdge == NULL){m_mVexs[p1].pFirstEdge = node1;}else{LinkLast(m_mVexs[p1].pFirstEdge, node1);}node2 = new ENode();node2->nVindex = p1;if (m_mVexs[p2].pFirstEdge == NULL){m_mVexs[p2].pFirstEdge = node2;}else{LinkLast(m_mVexs[p2].pFirstEdge, node2);}}}
(3)完整代码
#include "stdio.h" #include <iostream> using namespace std;#define MAX 100// 边 struct ENode {int nVindex; // 该边所指的顶点的位置ENode *pNext; // 指向下一个边的指针 };struct VNode {char data; // 顶点信息ENode *pFirstEdge; // 指向第一条依附该顶点的边 };// 无向邻接表 class listUDG { public:listUDG(){};listUDG(char *vexs, int vlen, char edges[][2], int elen){m_nVexNum = vlen;m_nEdgNum = elen;// 初始化"邻接表"的顶点for (int i = 0; i < vlen; i ++){m_mVexs[i].data = vexs[i];m_mVexs[i].pFirstEdge = NULL;}char c1,c2;int p1,p2;ENode *node1, *node2;// 初始化"邻接表"的边for (int j = 0; j < elen; j ++){// 读取边的起始顶点和结束顶点c1 = edges[j][0];c2 = edges[j][1];p1 = GetVIndex(c1);p2 = GetVIndex(c2);node1 = new ENode();node1->nVindex = p2;if (m_mVexs[p1].pFirstEdge == NULL){m_mVexs[p1].pFirstEdge = node1;}else{LinkLast(m_mVexs[p1].pFirstEdge, node1);}node2 = new ENode();node2->nVindex = p1;if (m_mVexs[p2].pFirstEdge == NULL){m_mVexs[p2].pFirstEdge = node2;}else{LinkLast(m_mVexs[p2].pFirstEdge, node2);}}}~listUDG(){ENode *pENode = NULL;ENode *pTemp = NULL;for (int i = 0; i < m_nVexNum; i ++){pENode = m_mVexs[i].pFirstEdge;if (pENode != NULL){pTemp = pENode;pENode = pENode->pNext;delete pTemp;}delete pENode;}}void PrintUDG(){ ENode *pTempNode = NULL;cout << "邻接无向表:" << endl;for (int i = 0; i < m_nVexNum; i ++){cout << "顶点:" << GetVIndex(m_mVexs[i].data)<< "-" << m_mVexs[i].data<< "->";pTempNode = m_mVexs[i].pFirstEdge;while (pTempNode){cout <<pTempNode->nVindex << "->";pTempNode = pTempNode->pNext;}cout << endl;}} private:// 返回顶点的索引int GetVIndex(char ch){int i = 0;for (; i < m_nVexNum; i ++){if (m_mVexs[i].data == ch){return i;}}return -1;}void LinkLast(ENode *pFirstNode, ENode *pNode){if (pFirstNode == NULL || pNode == NULL){return;}ENode *pTempNode = pFirstNode;while (pTempNode->pNext != NULL){pTempNode = pTempNode->pNext;}pTempNode->pNext = pNode;}private:int m_nVexNum; // 顶点数目int m_nEdgNum; // 边数目 VNode m_mVexs[MAX]; };void main() {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 = sizeof(vexs)/sizeof(vexs[0]); int elen = sizeof(edges)/sizeof(edges[0]); listUDG* pG = new listUDG(vexs, vlen, edges, elen); pG->PrintUDG(); // 打印图 return; }
View Code
邻接有向图
1. 邻接表有向图介绍
邻接表有向图是指通过邻接表表示的有向图。
上面的图G2包含了"A,B,C,D,E,F,G"共7个顶点,而且包含了"<A,B>,<B,C>,<B,E>,<B,F>,<C,E>,<D,C>,<E,B>,<E,D>,<F,G>"共9条边。
上 图右边的矩阵是G2在内存中的邻接表示意图。每一个顶点都包含一条链表,该链表记录了"该顶点所对应的出边的另一个顶点的序号"。例如,第1个顶点(顶点B)包含的链表所包含的节点的数据分别是"2,4,5";而这"2,4,5"分别对应"C,E,F"的序号,"C,E,F"都属于B的出边的另一个顶点。
2. 邻接表有向图代码实现
(1)数据结构
struct ENode {int nVindex; // 该边所指的顶点的位置ENode *pNext; // 指向下一个边的指针 };struct VNode {char data; // 顶点信息ENode *pFirstEdge; // 指向第一条依附该顶点的边 };
(2)邻接表有向图创建
listDG(char *vexs, int vlen, char edges[][2], int elen) {m_nVexNum = vlen;m_nEdgNum = elen;// 初始化"邻接表"的顶点for (int i = 0; i < vlen; i ++){m_mVexs[i].data = vexs[i];m_mVexs[i].pFirstEdge = NULL;}char c1,c2;int p1,p2;ENode *node1;// 初始化"邻接表"的边for (int j = 0; j < elen; j ++){// 读取边的起始顶点和结束顶点c1 = edges[j][0];c2 = edges[j][1];p1 = GetVIndex(c1);p2 = GetVIndex(c2);node1 = new ENode();node1->nVindex = p2;if (m_mVexs[p1].pFirstEdge == NULL){m_mVexs[p1].pFirstEdge = node1;}else{LinkLast(m_mVexs[p1].pFirstEdge, node1);}} }
(3)完整代码实现
#include "stdio.h" #include <iostream> using namespace std;#define MAX 100// 边 struct ENode {int nVindex; // 该边所指的顶点的位置ENode *pNext; // 指向下一个边的指针 };struct VNode {char data; // 顶点信息ENode *pFirstEdge; // 指向第一条依附该顶点的边 };// 有向邻接表 class listDG { public:listDG(){};listDG(char *vexs, int vlen, char edges[][2], int elen){m_nVexNum = vlen;m_nEdgNum = elen;// 初始化"邻接表"的顶点for (int i = 0; i < vlen; i ++){m_mVexs[i].data = vexs[i];m_mVexs[i].pFirstEdge = NULL;}char c1,c2;int p1,p2;ENode *node1;// 初始化"邻接表"的边for (int j = 0; j < elen; j ++){// 读取边的起始顶点和结束顶点c1 = edges[j][0];c2 = edges[j][1];p1 = GetVIndex(c1);p2 = GetVIndex(c2);node1 = new ENode();node1->nVindex = p2;if (m_mVexs[p1].pFirstEdge == NULL){m_mVexs[p1].pFirstEdge = node1;}else{LinkLast(m_mVexs[p1].pFirstEdge, node1);}}}~listDG(){ENode *pENode = NULL;ENode *pTemp = NULL;for (int i = 0; i < m_nVexNum; i ++){pENode = m_mVexs[i].pFirstEdge;if (pENode != NULL){pTemp = pENode;pENode = pENode->pNext;delete pTemp;}delete pENode;}}void PrintDG(){ ENode *pTempNode = NULL;cout << "邻接有向表:" << endl;for (int i = 0; i < m_nVexNum; i ++){cout << "顶点:" << GetVIndex(m_mVexs[i].data)<< "-" << m_mVexs[i].data<< "->";pTempNode = m_mVexs[i].pFirstEdge;while (pTempNode){cout <<pTempNode->nVindex << "->";pTempNode = pTempNode->pNext;}cout << endl;}} private:// 返回顶点的索引int GetVIndex(char ch){int i = 0;for (; i < m_nVexNum; i ++){if (m_mVexs[i].data == ch){return i;}}return -1;}void LinkLast(ENode *pFirstNode, ENode *pNode){if (pFirstNode == NULL || pNode == NULL){return;}ENode *pTempNode = pFirstNode;while (pTempNode->pNext != NULL){pTempNode = pTempNode->pNext;}pTempNode->pNext = pNode;}private:int m_nVexNum; // 顶点数目int m_nEdgNum; // 边数目 VNode m_mVexs[MAX]; };void main() {char vexs[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'}; char edges[][2] = { {'A', 'B'}, {'B', 'C'}, {'B', 'E'}, {'B', 'F'}, {'C', 'E'}, {'D', 'C'}, {'E', 'B'}, {'E', 'D'}, {'F', 'G'}}; int vlen = sizeof(vexs)/sizeof(vexs[0]); int elen = sizeof(edges)/sizeof(edges[0]); listDG *pG = new listDG(vexs, vlen, edges, elen); pG->PrintDG(); // 打印图 return; }
View Code
转载于:https://www.cnblogs.com/xiaobingqianrui/p/8917390.html
数据结构之图的创建(邻接表)相关推荐
- 数据结构之图:邻接矩阵和邻接表、深度优先遍历和广度优先遍历
简介 线性表是一种线性结构,除了头结点和尾节点,线性表的每个元素都只有一个前取节点和一个后继节点.而树结构则相较于线性表更加复杂,它描述的关系为数据元素之间的父子关系,也是现实世界父子关系的缩影, 一 ...
- 数据结构【图】—023邻接表深度和广度遍历
1 #include "000库函数.h" 2 //无向图 3 4 #define MAXSIZE 9 /* 存储空间初始分配量 */ 5 #define MAXEDGE 15 6 ...
- 数据结构——无向图创建邻接表以及深度遍历、广度遍历(C语言版)
摘自:数据结构--无向图创建邻接表以及深度遍历.广度遍历(C语言版) 作者:正弦定理 发布时间:2020-12-22 20:55:12 网址:https://blog.csdn.net/chinese ...
- 数据结构(廿六) -- C语言版 -- 图 - 图的遍历 -- 邻接表 - 深度/广度优先遍历/搜索(DFS、BFS)
内容预览 零.读前说明 一.深度优先遍历 1.1.深度优先的遍历过程 1.2.深度优先的遍历实现代码 二.广度优先遍历 2.1.广度优先的遍历过程 2.2.广度优先的遍历实现代码 三.源码测试效果 3 ...
- 图2——利用邻接表创建有向图
图2--利用邻接表创建有向图 图 假设以邻接表作为图的存储结构,编写算法,创建有向图并输出邻接表. 主要考查对邻接表的理解.图的邻接表分为两个部分:表头结点和边表结点,因此创建有向图也分成两部分:一是 ...
- C/C++语言 数据结构 创建邻接表存储的无向图及其邻接表的输出
目录 1.邻接表相关知识补充 2. 图的邻接存储表示 3.测试输入与输出样例 4.代码实现 4.1 创建无向图邻接表 4.2 输入无向图的邻接表 1.邻接表相关知识补充 定义: 对于图中每个顶点 vi ...
- 用邻接表存储图c语言,邻接表、邻接多重表、十字链表及C语言实现
上一节介绍了如何使用顺序存储结构存储邻接多重表和 邻接的意思是顶点之间有边或者弧存在,通过当前顶点,可以直接找到下一个顶点. 邻接表 使用邻接表存储图时,对于图中的每一个顶点和它相关的邻接点,都存储到 ...
- 数据结构之图(2-2)【邻接多重表】适用于无向图
邻接多重表(Adjacency Multilist)主要用于存储无向图.因为,如果用邻接表存储无向图,每条边的两个边结点分别在以该边 所依附的两个顶点为头结点的链表中,这给图的某些操作带来不便.例如, ...
- 图的建立-邻接表表示(C语言)
代码如下: /* 图的邻接表表示法 */#define MaxVertexNum 100 /* 最大顶点数设为100 */ typedef int Vertex; /* 用顶点下标表示顶点,为整型 * ...
最新文章
- 自动化测试的优势和局限性有哪些
- TensorFlow基于cifar10数据集实现进阶的卷积网络
- centos7根据进程号查看进程位置
- wps vba模块压缩包_01_创建第一个VBA小程序:你好,世界
- 马斯克:如果我不担任CEO 特斯拉就会完蛋
- 结对-贪吃蛇-最终程序
- php yii框架连接数据库,Yii 框架使用数据库(databases)的方法示例
- TensorFlow GPU配置
- linux es数据库 head,Elasticsearch 5.3.x 使用 Head 插件
- 由一道习题看如何设计浮点数
- 实现支付代付批量转账接口
- 卡尔曼滤波c语言程序,卡尔曼滤波算法及C语言实现
- 推荐 DBeaver 数据库管理工具 PD数据库建模
- Internet Explorer 包含五个预定义区域
- 微信支付-商家给小程序用户转账教程(全网最详细JAVA版)
- 代码整洁之道 1-3阅读笔记
- Android设备使用libusb和usb声卡
- C++和Rust_自从尝了 Rust,Java 突然不香了
- python控制鼠标点击_python模拟点击中如何操作鼠标位置?
- Centos7 安装Yarn