邻接多重表(Adjacency Multilist)主要用于存储无向图。因为,如果用邻接表存储无向图,每条边的两个边结点分别在以该边

所依附的两个顶点为头结点的链表中,这给图的某些操作带来不便。例如,对已访问过的边做标记,或者要删除图中某一条边等,

都需要找到表示同一条边的两个结点。因此,在进行这一类操作的无向图的问题中采用邻接多重表作存储结构更为适宜。

邻接多重表的存储结构和十字链表类似,也是由顶点表和边表组成,每一条边用一个结点表示,其顶点表结点结构和边表结点

结构如图8.15 所示。

其中,顶点表由两个域组成,vertex 域存储和该顶点相关的信息firstedge 域指示第一条依附于该顶点的边;边表结点由六个域

组成,mark 为标记域,可用以标记该条边是否被搜索过;ivex 和jvex 为该边依附的两个顶点在图中的位置;ilink 指向下一条依

附于顶点ivex的边;jlink 指向下一条依附于顶点jvex 的边,info 为指向和边相关的各种信息的指针域。

例如,图8.16 所示为无向图8.1 的邻接多重表。在邻接多重表中,所有依附于同一顶点的边串联在同一链表中,由于每条边依附于两个顶

点,则每个边结点同时链接在两个链表中。可见,对无向图而言,其邻接多重表和邻接表的差别,仅仅在于同一条边在邻接表中用两个结

点表示,而在邻接多重表中只有一个结点。因此,除了在边结点中增加一个标志域外,邻接多重表所需的存储量和邻接表相同。在邻接多

重表上,各种基本操作的实现亦和邻接表相似。

代码如下:

  1 #include "stdafx.h"
  2 #include<iostream>
  3 using namespace std;
  4
  5 typedef int VertexType;
  6 #define MAX_VERTEX_NUM 20
  7 typedef enum{unvisited,visited} VisitIf;
  8 typedef struct EBox
  9 {
 10     VisitIf mark;            //访问标记
 11     int ivex, jvex;          //该边依附的两个顶点的位置
 12     struct EBox *ilink, *jlink;//分别指向依附的两个顶点的下一条边
 13     int info;                //该边信息指针,可指向权值或其他信息
 14 }EBox;
 15 typedef struct VexBox
 16 {
 17     VertexType data;
 18     EBox *firstarc;          //指向第一条依附改点的边
 19 }VexBox;
 20 typedef struct
 21 {
 22     VexBox adjmulist[MAX_VERTEX_NUM];
 23     int vexnum, arcnum;      //无向图的当前顶点数和边数
 24 }AMLGraph;
 25
 26 int LocateVex(AMLGraph G, VertexType v)// 初始条件:无向图G存在,v和G中顶点有相同特征
 27                                        // 操作结果:若G中存在顶点v,则返回该顶点在无向图中位置;否则返回-1
 28 {
 29     for (int i = 0; i < G.vexnum; i++)
 30         if (G.adjmulist[i].data == v)
 31             return i;
 32     return -1;
 33 }
 34
 35 void CreateGraph(AMLGraph &G)//采用邻接多重表构建无向图G
 36 {
 37     VertexType v1, v2;
 38     cout << "请输入总顶点数和总边数(用空格隔开):";
 39     cin >> G.vexnum >> G.arcnum;
 40     cout << "输入顶点" << endl;
 41     for (int i = 0; i < G.vexnum; i++)//构造顶点向量
 42     {
 43         cin >> G.adjmulist[i].data ;
 44         G.adjmulist[i].firstarc = NULL;
 45     }
 46     cout << "请输入每条边的两个端点以及权值:" << endl;
 47     for (int k = 0; k < G.arcnum; k++)//构造表结点链表
 48     {
 49         EBox *p = new EBox;;
 50         cin >> v1 >> v2 >>p->info;
 51         int m = LocateVex(G, v1);//一端
 52         int n = LocateVex(G, v2);//另一端
 53         p->mark = unvisited;
 54         p->ivex = m;         //插在一端表头
 55         p->ilink = G.adjmulist[m].firstarc;
 56         G.adjmulist[m].firstarc = p;
 57         p->jvex = n;         //插在另一端表头
 58         p->jlink = G.adjmulist[n].firstarc;
 59         G.adjmulist[n].firstarc = p;
 60     }
 61 }
 62
 63 void MarkUnvizited(AMLGraph G)//置边的访问标记为未被访问
 64 {
 65     int i;
 66     EBox *p;
 67     for (i = 0; i<G.vexnum; i++)
 68     {
 69         p = G.adjmulist[i].firstarc;
 70         while (p)
 71         {
 72             p->mark = unvisited;
 73             if (p->ivex == i)
 74                 p = p->ilink;
 75             else
 76                 p = p->jlink;
 77         }
 78     }
 79 }
 80
 81
 82 void display(AMLGraph G)//输出无向图的邻接多重表
 83 {
 84     EBox *p;
 85     MarkUnvizited(G);
 86     cout << "无向图有" << G.vexnum << "个顶点,分别为:";
 87     for (int i = 0; i < G.vexnum; i++)
 88     {
 89         cout << G.adjmulist[i].data << " ";
 90
 91     }
 92         cout << endl;
 93         for (int i = 0; i < G.vexnum; i++)
 94         {
 95             cout << "和" << G.adjmulist[i].data << "有关的边:";
 96             p = G.adjmulist[i].firstarc;
 97             while (p)
 98             {
 99                 if (p->ivex == i) // 边的m端与该顶点有关
100                 {
101                     if (p->mark)
102                     {
103                         cout << G.adjmulist[i].data <<" "<< G.adjmulist[p->jvex].data<<"   ";
104                         p->mark = visited;
105                         if (p->info)
106                             cout << "权值:" << p->info << ". ";
107                     }
108                     p = p->ilink;
109                 }
110                 else              // 边的n端与该顶点有关
111                 {
112                     if (!p->mark)
113                     {
114                         cout << G.adjmulist[p->ivex].data <<" "<< G.adjmulist[i].data<<"   ";
115                         p->mark = visited;
116                         if (p->info)
117                             cout << "权值:" << p->info << ". ";
118                     }
119                     p = p->jlink;
120                 }
121             }
122             cout << endl;
123         }
124 }
125
126 int main()
127 {
128     AMLGraph MG;
129     CreateGraph(MG);
130     display(MG);
131     return 0;
132 }

输出结果:

转载于:https://www.cnblogs.com/Trojan00/p/8964609.html

数据结构之图(2-2)【邻接多重表】适用于无向图相关推荐

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

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

  2. 构建复杂网络的几种方法(邻接矩阵,邻接表,十字链表,邻接多重表)

    目录 1. 数据结构 线性结构 非线性结构 2. 复杂网络的数组表示 3. 复杂网络的邻接表表示 4. 邻接矩阵与邻接表的比较 5. 复杂网络的其他表示方法 逆邻接表 十字链表 邻接多重表 前向星 链 ...

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

    目录 1. 邻接矩阵表示法 1.1 图的邻接矩阵 1.2 创建有向网的邻接矩阵 2. 邻接表表示法 2.1 图的邻接表存储结构 2.2 创建有向图的邻接表 3. 十字链表表示法 3.1 图的十字链表存 ...

  4. 【图的存储】邻接多重表

    目录 前言 一.什么是邻接多重表? 二.邻接多重表的构成 1.顶点集+边集 2.顶点和边的连接 总结 前言   无论是什么程序都要和数据打交道,一个好的程序员会选择更优的数据结构来更好的解决问题,因此 ...

  5. 十字链表、邻接多重表

    邻接矩阵.邻接表存储有向图 十字链表存储有向图 十字链表是有向图的一种链式存储结构.在十字链表中,对应于有向图中的每条弧有一个结点,对应于每个顶点也有一个结点. 弧结点中有5个域:尾域(tailvex ...

  6. [转]数据结构:图的存储结构之邻接多重表

    1.引言: 若要删除左边的(V0,V2)这条边,需要对图下表的阴影两个结点进行删除操作. 2.邻接多重表的存储结构: iVex和jVex:是与某条边依附的两个顶点在顶点表中的下标. iLink:指向依 ...

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

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

  8. (王道408考研数据结构)第六章图-第二节1:图的存储结构(邻接矩阵、邻接表、十字链表和邻接多重表)

    文章目录 一:邻接矩阵--适合存储稠密图 (1)邻接矩阵定义 (2)代码 二:邻接表 (1)邻接表定义 (2)代码 (3)邻接表和邻接矩阵对比 三:十字链表(用于有向图) 四:邻接多重表(用于优化无向 ...

  9. 图的链式存储结构解析(邻接表、逆邻接表、十字链表、邻接多重表)

    图的矩阵表示法比较消耗空间,需要花费$ n 2 n^2 n2$个单元存储边(弧).在边数较少的情况下比较浪费.我们这里来讨论图的链式存储结构. 图的链式结构主要有四类:邻接表.逆邻接表.十字链表.邻接 ...

最新文章

  1. Copilot 真会砸了程序员的饭碗?
  2. HTTP/TCP/IP协议
  3. 跨物种脑-脑连接!听障人士通过豚鼠大脑听到了声音 | Nature
  4. Unity4.6新UI系统初探(uGUI)
  5. send/recv阻塞和非租塞不同
  6. 利用阿里云自定义镜像实现服务器数据/网站快速迁移
  7. 三个线程按顺序输出数字
  8. dingo php,dingo 配置
  9. 高等组合学笔记(十二):Bell多项式,二项式型多项式序列,Faà di Bruno公式
  10. 张朝阳:未来文娱重点将拍更多网剧 发展UGC、短视频社交和直播社交
  11. mfc c++string、char与char*之间的关系
  12. AutoLearnSkills.lua --升级自动学习技能
  13. 虚拟手游服务器,自己搭建手机游戏服务器
  14. Pelles C 五光十色中的一抹经典
  15. 【自动驾驶】浅谈自动驾驶在业界的发展
  16. C++ OpenCV(四):绘制几何图形
  17. DNA-蛋白翻译过程的Python实现
  18. Linux解压缩时报错: Error is not recoverable: exiting now
  19. C# winFrom中让MessageBox.Show显示到最顶层
  20. FFmpeg的基础知识

热门文章

  1. 阅读微信支付demo收获
  2. 开源 免费 java CMS - FreeCMS2.1 会员站内信
  3. Linux服务器通过rz/sz轻松上传下载文件
  4. selenium webdriver python 环境搭建
  5. 设置vim的默认工作路径同时与自动设当前编辑的文件所在目录为当前工作路径不冲突...
  6. LeetCode算法题13:DFS/BFS - 单词搜索
  7. react源码分析-setState分析
  8. web框架flask(4)——数据库
  9. 从mongodb中查询数据
  10. 5 个关于 API 中日期和时间设计规则