有向图和无向图用邻接矩阵储存

有向图和无向图用邻接矩阵储存一般存储图的方式有两种 一是用邻接矩阵表示 二是用邻接链表 所谓用邻接矩阵 是用一个二维数组存储 边使用矩阵来构建模型 这使得每一个顶点和其它顶点之间都有边的有无的表示的机会 若有边 则他们交点为 1 否则为 0 当然 如果是一副边有权值的图 交点存储的是他们边的权值 1 首先收一下无向图的存储 无向图的边的矩阵一定是一个对称矩阵 因为无向图只关心边是否存在 而不关心方向

一般存储图的方式有两种:一是用邻接矩阵表示,二是用邻接链表。

所谓用邻接矩阵,是用一个二维数组存储,边使用矩阵来构建模型,这使得每一个顶点和其它顶点之间都有边的有无 的 表示的机会。若有边,则他们交点 为1 ,否则为0。当然,如果是一副边有权值的图,交点存储的是他们边的权值。

1、首先收一下无向图的存储:

无向图的边的矩阵一定是一个对称矩阵,因为无向图只关心边是否存在,而不关心方向,V0和V1有边,那么V1和V0也有边。

因为这里不研究有圈图,所以主对角线都是0,输入V0和V1边的关系后,就不必输入V1和V0的关系了。

图解如下:

有向图和无向图用邻接矩阵储存有向图和无向图用邻接矩阵储存

实现代码如下:
#include       using namespace std; #define MAX_VERTEX 4 //4个顶点的图 typedef char DataType; typedef struct { DataType vertexArr[MAX_VERTEX]; //顶点元素数组 int edgeArr[MAX_VERTEX][ MAX_VERTEX]; //边矩阵二维数组 }ArrayGraph; void ArrayGraph_init(ArrayGraph *pGraph); void ArrayGraph_create(ArrayGraph *pGraph); void ArrayGraph_show(ArrayGraph *pGraph); int main() { ArrayGraph g; ArrayGraph_init(&g); //初始化图 ArrayGraph_create(&g); //创建图 ArrayGraph_show(&g); //打印图 return 0; } //初始化为一个无圈图 ,也就是边矩阵中,主对角线元素都是0 void ArrayGraph_init(ArrayGraph *pGraph) { for (int i = 0; i < MAX_VERTEX; i++) pGraph->edgeArr[i][i] = 0; } //输入一个图 void ArrayGraph_create(ArrayGraph *pGraph) { for (int i = 0; i < MAX_VERTEX; ++i) //填充顶点数组,也就是输入顶点元素 { printf("输入第%d个顶点值\n",i+1); scanf(" %c",&(pGraph->vertexArr[i])); } for (int j = 0; j         vertexArr[j],pGraph->vertexArr[i]); scanf("%d",&( pGraph->edgeArr[j][i])); pGraph->edgeArr[i][j] = pGraph->edgeArr[j][i]; //对称 } } } void ArrayGraph_show(ArrayGraph *pGraph) { printf("\n\n顶点元素如下\n"); for (int i = 0; i < MAX_VERTEX; ++i) { printf("%-5c", pGraph->vertexArr[i]); } printf("\n\n"); puts("边矩阵如下\n\n"); printf("%-2c",' '); for(int i=0;i           vertexArr[i]); putchar('\n'); for (int j = 0; j             vertexArr[j]); for (int i = 0; i < MAX_VERTEX; ++i) { printf("%-5d",pGraph->edgeArr[i][j]); } putchar('\n'); } printf("\n\n"); }                  

2、有向图的邻接矩阵存储:

使用邻接矩阵呢存储时,有向图和无向图的区别在与 边和弧矩阵的差别。因为弧是有方向的,所以我们 以对角线为界,将矩阵划分为2个区域:

左下区域表示出弧标记区域,坐上区域代表入弧标记区域

如  若代表弧的矩阵为arcArr

 arcArr[V2][V3] 为1,且在出弧标记区域,则说明 V3<------V2

 arcArr[V3][V2] 为0,且在入弧标记区域,则说明 V2—\—>V3

有向图和无向图用邻接矩阵储存 有向图和无向图用邻接矩阵储存
代码实现如下:

#include                                              #define MAX_VERTEX 4 typedef char DataType; //图中元素的目标数据类型 typedef struct { DataType vertexArr[MAX_VERTEX]; //顶点元素数组 int arcArr[MAX_VERTEX][MAX_VERTEX]; //弧矩阵二维数组 }ArrayGraph; void ArrayGraph_init(ArrayGraph *pGraph); void ArrayGraph_create(ArrayGraph *pGraph); void ArrayGraph_show(ArrayGraph *pGraph); int main() { ArrayGraph g; ArrayGraph_init(&g); ArrayGraph_create(&g); ArrayGraph_show(&g); return 0; } //初始化为一个无圈图 ,也就是弧矩阵中,主对角线元素都是0 void ArrayGraph_init(ArrayGraph *pGraph) { for (int i = 0; i < MAX_VERTEX; i++) pGraph->arcArr[i][i] = 0; } void ArrayGraph_create(ArrayGraph *pGraph) { for (int i = 0; i < MAX_VERTEX; ++i) //填充顶点数组 { printf("输入第%d个顶点值\n",i+1); scanf(" %c",&(pGraph->vertexArr[i])); } for (int j = 0; j                 vertexArr[i],pGraph->vertexArr[j]); scanf("%d",&( pGraph->arcArr[j][i])); printf("若元素%c有指向%c的弧,则输入1,否则输入0\t",pGraph->vertexArr[j],pGraph->vertexArr[i]); scanf("%d",&( pGraph->arcArr[i][j])); } } } void ArrayGraph_show(ArrayGraph *pGraph) { printf("\n\n顶点元素如下\n"); for (int i = 0; i < MAX_VERTEX; ++i) { printf("%-5c", pGraph->vertexArr[i]); } printf("\n\n"); puts("弧矩阵如下\n\n"); printf("%-2c",' '); for(int i=0;i                   vertexArr[i]); putchar('\n'); for (int j = 0; j                     vertexArr[j]); for (int i = 0; i < MAX_VERTEX; ++i) { printf("%-5d",pGraph->arcArr[i][j]); } putchar('\n'); } putchar('\n'); }                                  

3、有权值无向图(无向网)的邻接矩阵存储:

无向网的边是有权值的,这个值可以是任何一个合法的值,什么样的值是合法的呢?这需要根据图的具体用途来定。所以,我们不能用简单的0,1来代表边。

如果2个顶点无关联,他们也不能用0表示,因为0也可能是一个合法的wieght值。可有类比一下:如何地球上2个地方之间不可互通,那么他们之间的车程费是不是无穷大呢?

所以,我们来要根据图权值类型定义一个相应类型的最大值,来代表2个顶点之间不关联。

同样用一个例子。

 V0 V1之间的权值为12

V0 V2之间的权值为1

V0 V3之间的权值为5

V2 V3之间的权值为7

有向图和无向图用邻接矩阵储存 有向图和无向图用邻接矩阵储存

代码实现如下:

#include                                                                          #define MAX_VERTEX 4 #define INFINITY 65535 typedef char DataType; //存储的元素类型 typedef int WeightType; //权值的类型 typedef struct { DataType vertexArr[MAX_VERTEX]; //存储顶点的数组 WeightType edgeArr[MAX_VERTEX][MAX_VERTEX]; //存储边的二维数组 }UArrayNet; //数据结构类型:无向网 void UArrayNet_init(UArrayNet*pGraph); void UArrayNet_create(UArrayNet*pGraph); void UArrayNet_show(UArrayNet *pGraph); int main() { UArrayNet net; UArrayNet_init(&net); UArrayNet_create(&net); UArrayNet_show(&net); return 0; } void UArrayNet_init(UArrayNet*pGraph) { for (int i = 0; i < MAX_VERTEX; ++i) { pGraph->edgeArr[i][i] = INFINITY; } } void UArrayNet_create(UArrayNet*pGraph) { for (int i = 0; i < MAX_VERTEX; ++i) //填充顶点数组 { printf("输入第%d个顶点值\n", i + 1); scanf(" %c", &(pGraph->vertexArr[i])); } for (int j = 0; j                         vertexArr[j], pGraph->vertexArr[i], INFINITY); scanf("%d", &(pGraph->edgeArr[j][i])); pGraph->edgeArr[i][j] = pGraph->edgeArr[j][i]; //对称 } } } void UArrayNet_show(UArrayNet *pGraph) { printf("\n\n顶点元素如下\n"); for (int i = 0; i < MAX_VERTEX; ++i) { printf("%-5c", pGraph->vertexArr[i]); } printf("\n\n"); puts("边矩阵如下"); printf("%-2c", ' '); for (int i = 0; i                           vertexArr[i]); putchar('\n'); for (int j = 0; j                             vertexArr[j]); for (int i = 0; i < MAX_VERTEX; ++i) { if(pGraph->edgeArr[i][j]==INFINITY) { printf("%-5c", '#'); } else printf("%-5d", pGraph->edgeArr[i][j]); } putchar('\n'); } }                                                  

4、有向网邻接矩阵存储

有向网的实现与无向网思路一致,就不重复累赘了,直接上代码吧。

#include                                                                                 #define MAX_VERTEX 4 #define INFINITY 65535 typedef char DataType; //存储的元素类型 typedef int WeightType; //权值的类型 typedef struct { DataType vertexArr[MAX_VERTEX]; //存储顶点的数组 WeightType arcArr[MAX_VERTEX][MAX_VERTEX]; //存储边的二维数组 }UArrayNet; //数据结构类型:无向网 void UArrayNet_init(UArrayNet*pGraph); void UArrayNet_create(UArrayNet*pGraph); void UArrayNet_show(UArrayNet *pGraph); int main() { UArrayNet net; UArrayNet_init(&net); UArrayNet_create(&net); UArrayNet_show(&net); return 0; } void UArrayNet_init(UArrayNet*pGraph) { for (int i = 0; i < MAX_VERTEX; ++i) { pGraph->arcArr[i][i] = INFINITY; } } void UArrayNet_create(UArrayNet*pGraph) { for (int i = 0; i < MAX_VERTEX; ++i) //填充顶点数组 { printf("输入第%d个顶点值\n", i + 1); scanf(" %c", &(pGraph->vertexArr[i])); } for (int j = 0; j                           vertexArr[j], pGraph->vertexArr[i], INFINITY); scanf("%d",&( pGraph->arcArr[j][i])); printf("若元素%c有指向%c有边,则输入权值,否则输入无效值%d\t", pGraph->vertexArr[i], pGraph->vertexArr[j], INFINITY); scanf("%d",&( pGraph->arcArr[i][j])); } } } void UArrayNet_show(UArrayNet *pGraph) { printf("\n\n顶点元素如下\n"); for (int i = 0; i < MAX_VERTEX; ++i) { printf("%-5c", pGraph->vertexArr[i]); } printf("\n\n"); puts("边矩阵如下"); printf("%-2c", ' '); for (int i = 0; i                             vertexArr[i]); putchar('\n'); for (int j = 0; j                               vertexArr[j]); for (int i = 0; i < MAX_VERTEX; ++i) { if(pGraph->arcArr[i][j]==INFINITY) { printf("%-5c", '#'); } else printf("%-5d", pGraph->arcArr[i][j]); } putchar('\n'); } }                                                      














版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/227043.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午10:04
下一篇 2026年3月16日 下午10:04


相关推荐

  • Java中Random用法

    Java中Random用法今天看帖子时候看到了蓄水池算法,想起来之前看到过这样的题目,记录一下用到的Random类吧,面试写算法应该会碰到这样的题目。首先Random是随机生成数用法,介绍一下:1、Random.nextInt():这个用法就是生成一个Int范围里的一个随机数,用法举个例子:Randonmrandom=newRandom;System.out.println(random.nextInt());这时候输出的就是一个随机数,范围就是int的范围,当然括号里是可以填参数的,比如random.nextInt

    2022年7月7日
    23
  • jediscluster工具类_cannot get jedis connection

    jediscluster工具类_cannot get jedis connectionRedis集群是没法执行批量操作命令的,如mget,pipeline等。这是因为redis将集群划分为16383个哈希槽,不同的key会划分到不同的槽中。原生JedisCluster对批量操作的限制是mgetmset必须在一个槽;四种批量优化的方法1、串行mget在for循环中执行一条条的get; 需要n次网络时间;2、串行IO在客户端对所有key做CR…

    2026年4月13日
    4
  • 程序员垃圾简历长什么样?

    程序员垃圾简历长什么样?已经连续五年参加大厂校招、社招的技术面试工作,简历看的不下于万份这篇文章会用实例告诉你,什么是差的程序员简历!疫情快要结束了,各个公司也都开始春招了,作为即将红遍大江南北的新晋UP主,那当然要为小伙伴们做点事(手动狗头)。就在公众号里公开征简历,义务帮大家看,并一一点评。《启舰:春招在即,义务帮大家看看简历吧》一石激起千层浪,三天收到两百多封简历。花光了两个星期的所有空闲时…

    2022年5月21日
    42
  • 阿里云大模型服务平台(百炼)的API调用

    阿里云大模型服务平台(百炼)的API调用

    2026年3月13日
    1
  • 施密特触发器 & D触发器归纳总结

    施密特触发器 & D触发器归纳总结上篇文章归纳了单片机 I O 口输入输出的一些原理及不同点 芯片内部涉及到了施密特触发器和 D 触发器 本篇简单做下总结 一 施密特触发器工作原理二 D 触发器工作原理一 施密特触发器介绍简单介绍下施密特触用途场景 其中施密特有个最重要的特性即滞回特性 施密特有滞回的原因是因为器件工作的时候内部存在正反馈导致的 正反馈具体机理这里不展开赘述 1 去除抖动 消除电平转换时的小幅度抖动 2 波形转换 三角波正弦波转换成方波 3 脉冲波整形 消除矩形波在

    2026年3月16日
    0
  • IDEA热部署不生效解决方案

    IDEA热部署不生效解决方案今天尝试热部署,没想到弄了半天没反应,最后经查阅发现此问题,希望同样问题的这个没配置的去添加试下,希望能帮到你第一步pom文件引入坐标&lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-devtools…

    2022年6月3日
    321

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号