用邻接表构造图
第一节 图的基本概念
1. 图的定义和术语
图是一种数据结构。
ADT Graph{
数据对象 V :V是据有相同特性的数据元素的集合,称为顶点集。
数据关系 R :
R={VR}
VR={<v,w>|v,w∈V且P(v,w), <v,w>表示从v到w的弧,P(v,w)定义了弧<v,w>的意义或信息}
图中的数据元素通常称为顶点,V是顶点的有穷非空集合;VR是两个顶点之间的关系的集合,若顶点间是以有向的弧连接的,则该图称为有向图,若是以无向的边连接的则称为无向图。弧或边有权值的称为网,无权值的称为图。
2. 图的存储结构
邻接表、邻接多重表、十字链表和数组。这里我们只介绍数组表示法。
图的数组表示法:
用两个数组分别存储数据元素(顶点)的信息和数据元素之间的关系(边或弧)的信息。其形式描述如下:
//---------图的数组(邻接矩阵)存储表示----------
#define INFINITY INT_MAX //最大值
#define MAX_VERTEX_NUM 20 //最大顶点个数
Typedef enum{DG,DN,UDG,UDN} GraphKind; //有向图,有向网,无向图,无向网
Typedef struct ArcCell{
VRType adj; //顶点关系类型,对无权图,有1或0表示是否相邻;对带权图,则为权值类型。
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;
3.构造一个有向网
则所对应的邻接矩阵为:
代码如下
/*graph.h文件*/
//---------图的数组(邻接矩阵)存储表示---------- #include<stdio.h> #include <string.h> #include <stdlib.h> #define INFINITY 10000 //最大值 #define MAX_VERTEX_NUM 20 //最大顶点个数 typedef int VRType; typedef char VertexType; typedef char InfoType; typedef enum{DG,DN,UDG,UDN} GraphKind; //有向图,有向网,无向图,无向网 typedef struct ArcCell { VRType adj; //顶点关系类型,对无权图,有1或0表示是否相邻;对带权图,则为权值类型。 InfoType *info; //弧相关信息的指针 }ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; typedef struct { VertexType vexs[MAX_VERTEX_NUM]; //顶点向量 AdjMatrix arcs; //邻接矩阵 int vexnum,arcnum; //图的当前顶点数和弧数 }mgraph,*MGraph; int Locate_vexs(MGraph &g,VertexType v) //定位顶点位置 { for (int i=0;i<g->vexnum;i++) if (g->vexs[i]==v) return i; return -1; } void Print_mgraph(MGraph &g) //打印图 { int i; printf("邻接矩阵为:\n"); printf("┏ "); //五个空格 for (i=0;i<g->vexnum;i++) printf("%c ",g->vexs[i]); printf("\n\n"); for (i=0;i<g->vexnum;i++) { printf("%c ",g->vexs[i]); for (int j=0;j<g->vexnum;j++) { //输出矩阵,并且调整矩阵 if (g->arcs[i][j].adj>0&&g->arcs[i][j].adj<10) printf("%d ",g->arcs[i][j].adj); else if (g->arcs[i][j].adj>9&&g->arcs[i][j].adj<100) printf("%d ",g->arcs[i][j].adj); else if (g->arcs[i][j].adj>99&&g->arcs[i][j].adj<1000) printf("%d ",g->arcs[i][j].adj); else if (g->arcs[i][j].adj>999&&g->arcs[i][j].adj<10000) printf("%d ",g->arcs[i][j].adj); else if(g->arcs[i][j].adj==INFINITY) printf("∞ "); } printf("\n\n"); } } void Add_vexs(MGraph &g) //增加顶点 { printf("请输入顶点个数:"); scanf("%d",&g->vexnum); getchar();//吸收回车符 printf("请输入顶点字符串序列:"); for (int i=0;i<g->vexnum;i++) scanf("%c",&g->vexs[i]); } void Add_arcs(MGraph &g) //增加边 { printf("请输入边的条数:"); scanf("%d",&g->arcnum); VertexType v1,v2; int row,col; VRType weight;; printf("请输入权重和对应顶点,以空格隔开:\n"); for (int i=0;i<g->arcnum;i++) { scanf("%d %c %c",&weight,&v1,&v2); row=Locate_vexs(g,v1); col=Locate_vexs(g,v2); g->arcs[row][col].adj=weight; } } void Init_graph(MGraph &g) //初始化图 { g=(MGraph)malloc(sizeof(mgraph)); g->vexnum=0; g->arcnum=0; for (int i=0;i<MAX_VERTEX_NUM;i++) g->vexs[i]='0'; for (i=0;i<MAX_VERTEX_NUM;i++) for (int j=0;j<MAX_VERTEX_NUM;j++) { g->arcs[i][j].adj=INFINITY; g->arcs[i][j].info=NULL; } } void Create_mgraph(MGraph &g) //创建图 { Add_vexs(g); Add_arcs(g); }
/*Adjmatrix.cpp文件*/ #include "graph.h" int main() { printf("\t\t\t\t创建一个有向图\n"); MGraph g; Init_graph(g); Create_mgraph(g); Print_mgraph(g); return 0; }
运行结果如下图所示: