文字描述

  用两个数组分别存储顶点信息和边/弧信息。

示意图

算法分析

  构造一个采用邻接矩阵作存储结构、具有n个顶点和e条边的无向网(图)G的时间复杂度是(n*n + e*n), 其中对邻接矩阵G.arcs的初始化耗费了n*n的时间。

  借助于邻接矩阵容易判定两个顶点之间是否有边/弧相连,并容易求得各个顶点的度。对于无向图,顶点vi的度是邻接矩阵地i行(或第i列)的元素之和;对于有向图,第i行的元素之和为顶点vi的出度;第j列的元素之和为顶点vj的入度;

代码实现

 /*
以数组表示法(邻接矩阵)作为图的存储结构创建图。
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #define INFINITY 100000 //最大值
#define MAX_VERTEX_NUM 20 //最大顶点数
typedef enum {DG, DN, UDG, UDN} GraphKind; //{有向图,有向网,无向图,无向网}
typedef int VRType;
typedef char VertexType;
typedef struct{
char note[];
}InfoType;
typedef struct ArcCell{
VRType adj; //顶点关系类型:1)对无权图,用1或0表示相邻否;2)对带权图,则为权值类型
InfoType *info; //该弧相关信息的指针
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct{
VertexType vexs[MAX_VERTEX_NUM]; //顶点向量
AdjMatrix arcs; //邻接矩阵
int vexnum, arcnum; //图的当前顶点数和弧数
GraphKind kind; //图的种类标志
}MGraph; /*
若G中存在顶点u,则返回该顶点在图中位置;否则返回-1。
*/
int LocateVex(MGraph G, VertexType v){
int i = ;
for(i=; i<G.vexnum; i++){
if(G.vexs[i] == v){
return i;
}
}
return -;
} /*
采用数组表示法(邻接矩阵),构造无向网
*/
int CreateUDN(MGraph *G){
int i = , j = , k = , IncInfo = ;
int v1 = , v2 = , w = ;
char tmp[] = {}; printf("输入顶点数,弧数,其他信息标志位: ");
scanf("%d,%d,%d", &G->vexnum, &G->arcnum, &IncInfo); for(i=; i<G->vexnum; i++){
printf("input vexs %d: ", i+);
memset(tmp, , sizeof(tmp));
scanf("%s", tmp);
G->vexs[i] = tmp[];
}
for(i=; i<G->vexnum; i++){
for(j=; j<G->vexnum; j++){
G->arcs[i][j].adj = INFINITY;
G->arcs[i][j].info = NULL;
}
}
for(k=; k<G->arcnum; k++){
printf("输入第%d条弧: 顶点1, 顶点2,权值", k+);
memset(tmp, , sizeof(tmp));
scanf("%s", tmp);
sscanf(tmp, "%c,%c,%d", &v1, &v2, &w);
i = LocateVex(*G, v1);
j = LocateVex(*G, v2);
G->arcs[i][j].adj = w;
if(IncInfo){
//
}
G->arcs[j][i] = G->arcs[i][j];
}
return ;
} /*
采用数组表示法(邻接矩阵),构造无向图
*/
int CreateUDG(MGraph *G)
{
int i = , j = , k = , IncInfo = ;
int v1 = , v2 = , w = ;
char tmp[] = {}; printf("输入顶点数,弧数,其他信息标志位: ");
scanf("%d,%d,%d", &G->vexnum, &G->arcnum, &IncInfo); for(i=; i<G->vexnum; i++){
printf("输入第%d个顶点: ", i+);
memset(tmp, , sizeof(tmp));
scanf("%s", tmp);
G->vexs[i] = tmp[];
}
for(i=; i<G->vexnum; i++){
for(j=; j<G->vexnum; j++){
G->arcs[i][j].adj = ;
G->arcs[i][j].info = NULL;
}
}
for(k=; k<G->arcnum; k++){
printf("输入第%d条弧(顶点1, 顶点2): ", k+);
memset(tmp, , sizeof(tmp));
scanf("%s", tmp);
sscanf(tmp, "%c,%c", &v1, &v2, &w);
i = LocateVex(*G, v1);
j = LocateVex(*G, v2);
G->arcs[i][j].adj = ;
if(IncInfo){
//
}
G->arcs[j][i] = G->arcs[i][j];
}
return ;
} /*
采用数组表示法(邻接矩阵),构造图
*/
int CreateGraph(MGraph *G)
{
printf("输入图类型: -有向图(0), -有向网(1), +无向图(2), +无向网(3): ");
scanf("%d", &G->kind);
switch(G->kind){
case DG://构造有向图
case DN://构造有向网
printf("还不支持!\n");
return -;
case UDG://构造无向图
return CreateUDG(G);
case UDN://构造无向网
return CreateUDN(G);
default:
return -;
}
} /*
输出图的信息
*/
void printG(MGraph G)
{
if(G.kind == DG){
printf("类型:有向图;顶点数 %d, 弧数 %d\n", G.vexnum, G.arcnum);
}else if(G.kind == DN){
printf("类型:有向网;顶点数 %d, 弧数 %d\n", G.vexnum, G.arcnum);
}else if(G.kind == UDG){
printf("类型:无向图;顶点数 %d, 弧数 %d\n", G.vexnum, G.arcnum);
}else if(G.kind == UDN){
printf("类型:无向网;顶点数 %d, 弧数 %d\n", G.vexnum, G.arcnum);
}
int i = , j = ;
printf("\t");
for(i=; i<G.vexnum; i++){
printf("%c\t", G.vexs[i]);
}
printf("\n");
for(i=; i<G.vexnum; i++){
printf("%c\t", G.vexs[i]);
for(j=; j<G.vexnum; j++){
if(G.arcs[i][j].adj == INFINITY){
printf("INF\t");
}else{
printf("%d\t", G.arcs[i][j].adj);
}
}
printf("\n");
}
} int main(int argc, char *argv[])
{
MGraph G;
if(CreateGraph(&G) > -)
printG(G);
return ;
}

邻接矩阵存储结构(图)

代码运行

图->存储结构->数组表示法(邻接矩阵)的更多相关文章

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

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

  2. 图->存储结构->邻接多重表

    文字描述 邻接多重表是无向图的另一种链式存储结构. 虽然邻接表是无向图的一种很有效的存储结构,在邻接表中容易求得顶点和边的各种信息. 但是,在邻接表中每一条边(vi,vj)有两个结点,分别在第i个和第 ...

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

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

  4. 线性表(存储结构数组)--Java 实现

    /*线性表的数组实现 *特点:插入删除慢需要平均移动一半的数据,查找较快 *注意:有重复和无重复的数据对应的操作会有些不同 *注意数组一旦创建其大小就固定了 *Java集合长度可变是由于创建新的数组将 ...

  5. 优先队列(存储结构数组)--Java实现

    /*优先队列--是对队列的一种改进 *要存储的数据存在优先级--数值小的优先级高--在队头 *优先队列的实现 *1.数组:适合数据量小的情况(没有用rear+front实现) *优先队列头在items ...

  6. 队列(存储结构数组)--Java实现

    /*队列:其实也是一种操作受限的线性表 *特点:先进先出 *队尾指针:负责元素的进队 *队头指针:负责元素的出队 *注意:普通队--容易浪费空间,一般队列使用最多的就是循环队列--指针环绕 *队列的实 ...

  7. 有序线性表(存储结构数组)--Java实现

    /*有序数组:主要是为了提高查找的效率 *查找:无序数组--顺序查找,有序数组--折半查找 *其中插入比无序数组慢 * */ public class MyOrderedArray { private ...

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

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

  9. 存储结构与邻接矩阵,深度优先和广度优先遍历及Java实现

    如果看完本篇博客任有不明白的地方,可以去看一下<大话数据结构>的7.4以及7.5,讲得比较易懂,不过是用C实现 下面内容来自segmentfault 存储结构 要存储一个图,我们知道图既有 ...

随机推荐

  1. remmina如何上传文件到linux服务器

    1.安装filezilla 2. remmina中选择列表中的主机,点击“外部工具 -> filezilla-xfp.sh” 3. 弹出filezilla,输入主机,端口,用户名,密码,连接, ...

  2. 【九天教您南方cass 9.1】02 从地形图上绘制纵横断面

    同学们大家好,欢迎收看由老王测量上班记出品的cass9.1视频课程, 测量空间的[九天教您南方cass]专栏是九天老师专门开设cass免费教学班.希望能帮助那些刚入行的同学,并祝您一臂之力. [点击索 ...

  3. 数据中心内负载均衡-ECMP的使用分析

    背景 数据中心的网络拓扑通常采用CLOS结构,主机之间常存在多条路径.数据中心为满足吞吐量敏感型流量的需求会提供大量的带宽资源.那么利用数据中心这种网络拓扑已知,路径资源.带宽资源丰富的特性,可以更好 ...

  4. 使用Redis List简单实现抢红包

    在这里不讨论抢红包的算法,只用redis简单尝试解决抢红包.借助redis单线程和List的POP方法. static void Main(string[] args) { IRedisHelper ...

  5. [Model] AlexNet

    CaffeNet - a variant of AlexNet Ref: Classification: Instant Recognition with Caffe This is caffeNet ...

  6. Google Colab 免费GPU服务器使用教程

    Google免费GPU使用教程(亲测可用)   今天突然看到一篇推文,里面讲解了如何薅资本主义羊毛,即如何免费使用Google免费提供的GPU使用权. 可以免费使用的方式就是通过Google Cola ...

  7. 技巧:Vim 的纵向编辑模式

    https://www.ibm.com/developerworks/cn/linux/l-cn-vimcolumn/ 开始之前 人类大脑对文字的处理是平面式的,所以我们浏览文章.查找资料或者重构代码 ...

  8. 【netcore基础】MVC API全局异常捕捉中间件ExceptionHandlerMiddleWare

    项目中想通过统一的接口格式返回异常信息,而不是404 500等HTTP协议层的异常响应 例如 { , , "message":"用户名或密码不正确", &quo ...

  9. 使用iozone测试磁盘性能

    IOzone是一个文件系统测试基准工具.可以测试不同的操作系统中文件系统的读写性能.可以通过 write, re-write, read, re-read, random read, random w ...

  10. Go语言学习笔记1

    1.Go语言环境搭建及基础知识 Go语言官方网站(http://golang.org) 代码包文档网站(http://godoc.org) Go语言中文网(http://studygolang.com ...