数据结构之图的基本概念中了解了图的基本概念,接下来对图的代码实现进行详解。

邻接无向图

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

数据结构之图的创建(邻接表)相关推荐

  1. 数据结构之图:邻接矩阵和邻接表、深度优先遍历和广度优先遍历

    简介 线性表是一种线性结构,除了头结点和尾节点,线性表的每个元素都只有一个前取节点和一个后继节点.而树结构则相较于线性表更加复杂,它描述的关系为数据元素之间的父子关系,也是现实世界父子关系的缩影, 一 ...

  2. 数据结构【图】—023邻接表深度和广度遍历

    1 #include "000库函数.h" 2 //无向图 3 4 #define MAXSIZE 9 /* 存储空间初始分配量 */ 5 #define MAXEDGE 15 6 ...

  3. 数据结构——无向图创建邻接表以及深度遍历、广度遍历(C语言版)

    摘自:数据结构--无向图创建邻接表以及深度遍历.广度遍历(C语言版) 作者:正弦定理 发布时间:2020-12-22 20:55:12 网址:https://blog.csdn.net/chinese ...

  4. 数据结构(廿六) -- C语言版 -- 图 - 图的遍历 -- 邻接表 - 深度/广度优先遍历/搜索(DFS、BFS)

    内容预览 零.读前说明 一.深度优先遍历 1.1.深度优先的遍历过程 1.2.深度优先的遍历实现代码 二.广度优先遍历 2.1.广度优先的遍历过程 2.2.广度优先的遍历实现代码 三.源码测试效果 3 ...

  5. 图2——利用邻接表创建有向图

    图2--利用邻接表创建有向图 图 假设以邻接表作为图的存储结构,编写算法,创建有向图并输出邻接表. 主要考查对邻接表的理解.图的邻接表分为两个部分:表头结点和边表结点,因此创建有向图也分成两部分:一是 ...

  6. C/C++语言 数据结构 创建邻接表存储的无向图及其邻接表的输出

    目录 1.邻接表相关知识补充 2. 图的邻接存储表示 3.测试输入与输出样例 4.代码实现 4.1 创建无向图邻接表 4.2 输入无向图的邻接表 1.邻接表相关知识补充 定义: 对于图中每个顶点 vi ...

  7. 用邻接表存储图c语言,邻接表、邻接多重表、十字链表及C语言实现

    上一节介绍了如何使用顺序存储结构存储邻接多重表和 邻接的意思是顶点之间有边或者弧存在,通过当前顶点,可以直接找到下一个顶点. 邻接表 使用邻接表存储图时,对于图中的每一个顶点和它相关的邻接点,都存储到 ...

  8. 数据结构之图(2-2)【邻接多重表】适用于无向图

    邻接多重表(Adjacency Multilist)主要用于存储无向图.因为,如果用邻接表存储无向图,每条边的两个边结点分别在以该边 所依附的两个顶点为头结点的链表中,这给图的某些操作带来不便.例如, ...

  9. 图的建立-邻接表表示(C语言)

    代码如下: /* 图的邻接表表示法 */#define MaxVertexNum 100 /* 最大顶点数设为100 */ typedef int Vertex; /* 用顶点下标表示顶点,为整型 * ...

最新文章

  1. 自动化测试的优势和局限性有哪些
  2. TensorFlow基于cifar10数据集实现进阶的卷积网络
  3. centos7根据进程号查看进程位置
  4. wps vba模块压缩包_01_创建第一个VBA小程序:你好,世界
  5. 马斯克:如果我不担任CEO 特斯拉就会完蛋
  6. 结对-贪吃蛇-最终程序
  7. php yii框架连接数据库,Yii 框架使用数据库(databases)的方法示例
  8. TensorFlow GPU配置
  9. linux es数据库 head,Elasticsearch 5.3.x 使用 Head 插件
  10. 由一道习题看如何设计浮点数
  11. 实现支付代付批量转账接口
  12. 卡尔曼滤波c语言程序,卡尔曼滤波算法及C语言实现
  13. 推荐 DBeaver 数据库管理工具 PD数据库建模
  14. Internet Explorer 包含五个预定义区域
  15. 微信支付-商家给小程序用户转账教程(全网最详细JAVA版)
  16. 代码整洁之道 1-3阅读笔记
  17. Android设备使用libusb和usb声卡
  18. C++和Rust_自从尝了 Rust,Java 突然不香了
  19. python控制鼠标点击_python模拟点击中如何操作鼠标位置?
  20. Centos7 安装Yarn

热门文章

  1. 比较两个ListT是否相同
  2. 【Matlab开发】MATLAB编译C/C++代码
  3. 2014Esri国际用户大会ArcGIS Online
  4. 文本文件如何在其他地方打开
  5. hdu 2514 Another Eight Puzzle
  6. web developer tips (39):在Visual Studio 2008中取消远程web操作
  7. Apache服务器主配置文件 httpd.conf 中文版
  8. 改变linux终端颜色
  9. CloudStack的部署架构概览
  10. python制作缩略图