文字描述

  邻接多重表是无向图的另一种链式存储结构. 虽然邻接表是无向图的一种很有效的存储结构,在邻接表中容易求得顶点和边的各种信息. 但是,在邻接表中每一条边(vi,vj)有两个结点,分别在第i个和第j个链表中,这给某些图的操作带来不便。如对已被搜索过的边作记号或删除一条边等,此时需要找到表示同一条边的两个结点。因此,在进行这类操作的无向图的问题中采用邻接多重表更合适。

  邻接多重表的结构和十字链表类型。边结点和顶点结点如下示:

  

  

  边结点由6个域组成:mark为标志域,可标记这条边是否被搜索过; ivex和jvex为该边依附的两个顶点在图中的位置;ilink指向下一条依附于顶点ivex的边;jlink指向下一条依附于顶点jvex的边,info为指向和边相关的各种信息的指针域。

  顶点结点由2个域组成:data存储和该顶点相关的信息如顶点名称;firstedge域指示第一条依附于该顶点的边。

示意图

算法分析

  建立邻接多重链表的时间复杂度和建立邻接表是相同的. 另外邻接多重表几乎只针对无向图或无向网。

代码实现

 /*
以邻接多重表作为图的存储结构创建无向图。
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #define MAX_VERTEX_NUM 20
typedef enum {DG, DN, UDG, UDN} GraphKind;
typedef enum {unvisited, visited} VisitIf;
typedef char InfoType;
typedef char VertexType;
//顶点结点
typedef struct EBox{
VisitIf mark;//访问标记
int ivex, jvex;//该边依附的两个顶点的位置
struct EBox *ilink, *jlink;//分别指向依附这两个顶点的下一条边
InfoType *info;//该边信息指针
}EBox;
//边结点
typedef struct VexBox{
VertexType data;//存储顶点名称
EBox *firstedge;//指向第一条依附该顶点的边
}VexBox;
//图结点
typedef struct{
VexBox adjmulist[MAX_VERTEX_NUM];
int vexnum,edgenum; //无向图的当前顶点数和边数
GraphKind kind;
}AMLGraph; /*
若G中存在顶点u,则返回该顶点在图中位置;否则返回-1。
*/
int LocateVex(AMLGraph G, VertexType v)
{
int i = ;
for(i=; i<G.vexnum; i++){
if(v == G.adjmulist[i].data)
return i;
}
return -;
} /*
若G中存在顶点位置loc存在,则返回其顶点名称
*/
VertexType LocateVInfo(AMLGraph G, int loc){
return G.adjmulist[loc].data;
} /*
采用邻接多重表的存储结构,构造无向图
*/
int CreateUDG(AMLGraph *G)
{
int i = , j = , k = , IncInfo = ;
int vi = , vj = ;
char tmp[] = {};
EBox *p = NULL; printf("输入顶点数,边数,其他信息标志位: ");
scanf("%d,%d,%d", &G->vexnum, &G->edgenum, &IncInfo); for(i=; i<G->vexnum; i++){
//输入顶点值
printf("输入第%d个顶点: ", i+);
memset(tmp, , sizeof(tmp));
scanf("%s", tmp);
G->adjmulist[i].data = tmp[];
G->adjmulist[i].firstedge = NULL;
}
for(k=; k<G->edgenum; k++){
printf("输入第%d条边(顶点1, 顶点2): ", k+);
memset(tmp, , sizeof(tmp));
scanf("%s", tmp);
sscanf(tmp, "%c,%c", &vi, &vj);
i = LocateVex(*G, vi);
j = LocateVex(*G, vj);
p = (EBox*)malloc(sizeof(EBox));
p->ivex = i;
p->jvex = j;
p->mark = unvisited;
p->ilink = G->adjmulist[i].firstedge;
p->jlink = G->adjmulist[j].firstedge;
G->adjmulist[i].firstedge = p;
G->adjmulist[j].firstedge = p;
if(IncInfo){
//Input(p->info);
}
}
return ;
} /*
采用邻接多重表的存储结构,构造图
*/
int CreateGrap(AMLGraph *G)
{
printf("输入图类型: -有向图(0), -有向网(1), +无向图(2), -无向网(3): ");
scanf("%d", &G->kind);
switch(G->kind){
case DG:
case DN:
default:
printf("还不支持!\n");
return -;
case UDG:
return CreateUDG(G);
}
return ;
} /*
输出图的信息
*/
void printG(AMLGraph G)
{
if(G.kind == DG){
printf("类型:有向图;顶点数 %d, 边数 %d\n", G.vexnum, G.edgenum);
}else if(G.kind == DN){
printf("类型:有向网;顶点数 %d, 边数 %d\n", G.vexnum, G.edgenum);
}else if(G.kind == UDG){
printf("类型:无向图;顶点数 %d, 边数 %d\n", G.vexnum, G.edgenum);
}else if(G.kind == UDN){
printf("类型:无向网;顶点数 %d, 边数 %d\n", G.vexnum, G.edgenum);
}
int i = ;
EBox *vi = NULL;
EBox *vj = NULL;
EBox *vf = NULL;
for(i=; i<G.vexnum; i++){
printf("%c(%d): ", G.adjmulist[i].data, i);
vf = G.adjmulist[i].firstedge;
vi = vf->ilink;
vj = vf->jlink;
printf("fistedge:%c(%d)->%c(%d); ", LocateVInfo(G, vf->ivex), vf->ivex, LocateVInfo(G, vf->jvex), vf->jvex);
printf(" || ilink:");
while(vi){
printf("%c(%d)->%c(%d);", LocateVInfo(G, vi->ivex), vi->ivex, LocateVInfo(G, vi->jvex), vi->jvex);
vi = vi->ilink;
}
printf(" || jlink:");
while(vj){
printf("%c(%d)->%c(%d);", LocateVInfo(G, vj->ivex), vj->ivex, LocateVInfo(G, vj->jvex), vj->jvex);
vj = vj->jlink;
}
printf("\n");
}
return ;
} int main(int argc, char *argv[])
{
AMLGraph G;
if(CreateGrap(&G) > -){
printG(G);
}
return ;
}

邻接多重表存储结构(图)

代码运行

图->存储结构->邻接多重表的更多相关文章

  1. 图->存储结构->邻接表

    文字描述 邻接表是图的一种链式存储结构.在邻接表中,对图中每个顶点建立一个单链表,第i个单链表的结点表示依附顶点vi的边(对有向图是指以顶点vi为尾的弧).单链表中的每个结点由3个域组成,其中邻接点域 ...

  2. 图的邻接多重表和搜索(C++版本)

    最近在学数据结构,学到图这一章,网上的C++版本的代码乱得不行,所以自己写了一个完整C++版本的放这里. 用邻接多重表表示一个无向图,并给出DFS和BFS搜索代码.邻接多重表好处就是贼直观,几条边就几 ...

  3. 图->存储结构->十字链表

    文字描述 十字链表是有向图的另一种链式存储结构. 在十字链表中,对应于有向图中每一条弧有一个结点,对应于每个顶点也有一个结点.这些结点的结构如下所示: 在弧结点中有5个域: 尾域tailvex和头域h ...

  4. 图->存储结构->数组表示法(邻接矩阵)

    文字描述 用两个数组分别存储顶点信息和边/弧信息. 示意图 算法分析 构造一个采用邻接矩阵作存储结构.具有n个顶点和e条边的无向网(图)G的时间复杂度是(n*n + e*n), 其中对邻接矩阵G.ar ...

  5. Berkeley DB的数据存储结构——哈希表(Hash Table)、B树(BTree)、队列(Queue)、记录号(Recno)

    Berkeley DB的数据存储结构 BDB支持四种数据存储结构及相应算法,官方称为访问方法(Access Method),分别是哈希表(Hash Table).B树(BTree).队列(Queue) ...

  6. 【oracle11g,18】存储结构:暂时表,手工条带化,表/索引迁移表空间,删除表,外部表

    一. 暂时表 暂时表放在暂时表空间,不生成redo,仅仅有undo. 在暂时表中能够创建索引.视图及触发器,还能够使用"Export and Import(导出和导入)"或&quo ...

  7. 图的存储结构与操作--C语言实现

    图(graph)是一种比树结构还要复杂的数据结构,它的术语,存储方式,遍历方式,用途都比较广,所以如果想要一次性完成所有的代码,那代码会非常长.所以,我将分两次来完成图的代码.这一次,我会完成图的五种 ...

  8. C++编程练习(9)----“图的存储结构以及图的遍历“(邻接矩阵、深度优先遍历、广度优先遍历)

    图的存储结构 1)邻接矩阵 用两个数组来表示图,一个一维数组存储图中顶点信息,一个二维数组(邻接矩阵)存储图中边或弧的信息. 2)邻接表 3)十字链表 4)邻接多重表 5)边集数组 本文只用代码实现用 ...

  9. 【PHP数据结构】图的存储结构

    图的概念介绍得差不多了,大家可以消化消化再继续学习后面的内容.如果没有什么问题的话,我们就继续学习接下来的内容.当然,这还不是最麻烦的地方,因为今天我们只是介绍图的存储结构而已. 图的顺序存储结构:邻 ...

随机推荐

  1. Selenium Web 自动化 - 如何找到元素

    Selenium Web 自动化 - 如何找到元素 2016-07-29 1. 什么是元素? 元素:http://www.w3school.com.cn/html/html_elements.asp ...

  2. Linux免密码登录设置 && 设置快捷键

    看到这篇文章,你肯定是有这种需求. 假设要登录的机器为192.168.1.100,当前登录的机器为192.168.1.101. 首先在101的机器上生成密钥(如果已经生成可以跳过): $ ssh-ke ...

  3. 【iCore4 双核心板_ARM】例程十九:USBD_MSC实验——虚拟U盘

    实验步骤: 1.将SD卡插在SD卡槽中. 2.将跳线冒跳至USB_OTG,将USB_OTG通过Micor USB线与USB主机(电脑)相连. 3.烧写程序,我的电脑中将出现一个磁盘. 实验现象: 核心 ...

  4. JVM 内部原理(四)— 基本概念之 JVM 结构

    JVM 内部原理(四)- 基本概念之 JVM 结构 介绍 版本:Java SE 7 每位使用 Java 的程序员都知道 Java 字节码在 Java 运行时(JRE - Java Runtime En ...

  5. Java知多少(48)try语句的嵌套

    Try语句可以被嵌套.也就是说,一个try语句可以在另一个try块内部.每次进入try语句,异常的前后关系都会被推入堆栈.如果一个内部的try语句不含特殊异常的catch处理程序,堆栈将弹出,下一个t ...

  6. c++ 动态判断基类指针指向的子类类型(typeid)

    我们在程序中定义了一个基类,该基类有n个子类,为了方便,我们经常定义一个基类的指针数组,数组中的每一项指向都指向一个子类,那么在程序中我们如何判断这些基类指针是指向哪个子类呢? 本文提供了两种方法 ( ...

  7. [Paper] **Before GAN: sparse coding

    读罢[UFLDL] ConvNet,为了知识体系的完整,看来需要实战几篇论文深入理解一些原理. 如下是未来博文系列的初步设想,为了hold住 GAN而必备的知识体系,也是必经之路. [Paper] B ...

  8. 排序算法--选择排序(Selection Sort)_C#程序实现

    排序算法--选择排序(Selection Sort)_C#程序实现 排序(Sort)是计算机程序设计中的一种重要操作,也是日常生活中经常遇到的问题.例如,字典中的单词是以字母的顺序排列,否则,使用起来 ...

  9. mdadm命令详解

    创建阵列(-C或--create) --raid-devices(-n) 功能:指定阵列中成员盘个数. 举例:mdadm --create /dev/md0 -l5 -n2 /dev/sdb /dev ...

  10. MVC的ViewData自动给Razor写的input赋值

    问题: 写编辑的时候,突然发现,没有值的model,突然出现了值,而且值是ViewData中值. 后台: this.ViewData["test"] = "测试" ...