无向图:V是顶点的集合,VR是弧的集合,弧用(顶点,顶点)表示。有n个顶点,n(n-1)/2条弧的图,是无向完全图。
权:图的弧的相关系数。
网:带权的图。
子图:顶点和弧都包含于原图的图
邻接:两顶点之间有弧,则无向图a、b互为邻接点,有向图a邻接到b。
依附:弧依附于其两个顶点。
顶点的度:与顶点相关联的弧的个数。有向图有入度、出度之分。
路径:从a到b途径顶点组成的序列。有向图路径有向,无向图路径无向。
路径长度:路径上弧的个数。
回路/环:第一个顶点和最后一个顶点相同的路径。
简单路径:顶点不重复的路径。
简单回路/环:除第一个和最后一个顶点外,其余顶点不重复的回路。
连通:某两个顶点间有路径,则这两个顶点连通。
连通图:无向图中任意两个顶点都连通的图。
连通分量:无向图中能够连通极大节点个数的子图。
强连通图:有向图中任意两个顶点间相互有路径的图。
强连通分量:有向图中能够连通极大节点个数的子图(不一定顶点相互有路径,有一方有就行)。
连通图的生成树:包含连通图所有的n个顶点,却只有n-1个边。加上一个边就形成环。
有向树:仅有一个顶点入度为0,其余顶点入度均为1的有向图。
有向图的生成森林:由若干个不相交的有向树组成,这些有向树包含了有向图的所有顶点,却不包含所有边。
图的存储结构:数组表示法、邻接法、十字链表、邻接多重表。
本文针对数组表示法。
数组存储法用两个数组存储顶点和边信息。
顶点就是char型数组,边是一个包含权和其他信息的结构体构成的矩阵数组。
权:图的弧的相关系数。
网:带权的图。
子图:顶点和弧都包含于原图的图
邻接:两顶点之间有弧,则无向图a、b互为邻接点,有向图a邻接到b。
依附:弧依附于其两个顶点。
顶点的度:与顶点相关联的弧的个数。有向图有入度、出度之分。
路径:从a到b途径顶点组成的序列。有向图路径有向,无向图路径无向。
路径长度:路径上弧的个数。
回路/环:第一个顶点和最后一个顶点相同的路径。
简单路径:顶点不重复的路径。
简单回路/环:除第一个和最后一个顶点外,其余顶点不重复的回路。
连通:某两个顶点间有路径,则这两个顶点连通。
连通图:无向图中任意两个顶点都连通的图。
连通分量:无向图中能够连通极大节点个数的子图。
强连通图:有向图中任意两个顶点间相互有路径的图。
强连通分量:有向图中能够连通极大节点个数的子图(不一定顶点相互有路径,有一方有就行)。
连通图的生成树:包含连通图所有的n个顶点,却只有n-1个边。加上一个边就形成环。
有向树:仅有一个顶点入度为0,其余顶点入度均为1的有向图。
有向图的生成森林:由若干个不相交的有向树组成,这些有向树包含了有向图的所有顶点,却不包含所有边。
图的存储结构:数组表示法、邻接法、十字链表、邻接多重表。
本文针对数组表示法。
数组存储法用两个数组存储顶点和边信息。
顶点就是char型数组,边是一个包含权和其他信息的结构体构成的矩阵数组。
指向图的指针不仅要包含顶点和边,还要包含当前顶点数和边数。为了将4种图结合起来写成一个函数,又加上了图种类的元素。
程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#define MAX_VERTEX_NUM 20 //最大顶点个数
typedef enum {DG,DN,UDG,AN} GraphKind; //{有向图,有向网,无向图,无向网}
#define MAX_NAME 5 //顶点字符串的最大长度+1
#define MAX_INFO 20 //相关信息字符串的最大长度+1
typedef int status;
typedef char VertexType[MAX_NAME];
int has_info = 0;
typedef struct
{
int adj; //边有无
char *info; //该边相关信息的指针
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef struct
{
VertexType vertex[MAX_VERTEX_NUM]; //顶点数组,每一个元素是char型数组
AdjMatrix arcs; //邻接矩阵,每一个元素代表一条边
int vexnum,arcnum; //图的当前顶点数和弧数
GraphKind kind; //图的种类标志
}Graph; //图
//查找G中u顶点位置并返回
int locate_vertex(Graph *G,VertexType u)
{
int i;
for(i = 0;i < G->vexnum;++i)
if(strcmp(u,G->vertex[i]) == 0)
return i;
return -1;
}
//创建有向图
status CreateDG(Graph *G)
{
int i,j,k,l;
char s[MAX_INFO],*info;
VertexType va,vb;
printf("please input the directed graph's vertex number, edge number, and if the edge has information(yes:1, no:0): ");
scanf("%d %d %d",&G->vexnum,&G->arcnum,&has_info); //输入顶点个数,边个数及是否有其他信息
printf("please input %d string of vertex value(<%d chars of each string):\n",G->vexnum,MAX_NAME);
for(i = 0;i < G->vexnum;i++) //设置顶点
scanf("%s",G->vertex[i]);
for(i = 0;i < G->vexnum;++i) //邻接矩阵置空
for(j = 0;j < G->vexnum;++j){
G->arcs[i][j].adj = 0;
G->arcs[i][j].info = NULL;
}
printf("please input tail head of %d edges in order: \n",G->arcnum); //设置邻接矩阵
for(k = 0;k < G->arcnum;++k){
printf("%d 's edge:\n",k + 1);
scanf("%s %s",va,vb);
i = locate_vertex(G,va);
j = locate_vertex(G,vb);
G->arcs[i][j].adj = 1; //设置邻接矩阵
if(has_info){
printf("please input the information of this edge(<%d chars of this edge): ",MAX_INFO);
scanf("%s",s);
l = strlen(s);
if(l){
info = (char*)malloc((l + 1) * sizeof(char));
strcpy(info,s);
G->arcs[i][j].info = info;
}
}
}
G->kind = DG;
return 1;
}
//创建有向网
status CreateDN(Graph *G)
{
int i,j,k,l,w;
char s[MAX_INFO],*info;
VertexType va,vb;
printf("please input the directed graph's vertex number, edge number, and if the edge has information(yes:1, no:0): ");
scanf("%d %d %d",&G->vexnum,&G->arcnum,&has_info); //输入顶点个数,边个数及是否有其他信息
printf("please input %d string of vertex value(<%d chars of each string):\n",G->vexnum,MAX_NAME);
for(i = 0;i < G->vexnum;++i) //依次输入顶点的值
scanf("%s",G->vertex[i]);
for(i = 0;i < G->vexnum;++i) //邻接矩阵置空
for(j = 0;j < G->vexnum;++j){
G->arcs[i][j].adj = INT_MAX;
G->arcs[i][j].info = NULL;
}
printf("please input tail head power of %d edges in order: \n",G->arcnum);
for(k = 0;k < G->arcnum;++k){
printf("%d 's edge:\n",k + 1);
scanf("%s %s %d",va,vb,&w);
i = locate_vertex(G,va);
j = locate_vertex(G,vb);
G->arcs[i][j].adj = w; //设置邻接矩阵
if(has_info){
printf("please input the information of this edge(<%d chars of this edge): ",MAX_INFO);
scanf("%s",s);
l = strlen(s);
if(l){
info = (char*)malloc((l + 1) * sizeof(char));
strcpy(info,s);
G->arcs[i][j].info = info;
}
}
}
G->kind = DN;
return 1;
}
//创建无向图
status CreateUDG(Graph *G)
{
int i,j,k,l;
char s[MAX_INFO],*info;
VertexType va,vb;
printf("please input the undirected graph's vertex number, edge number, and if the edge has information(yes:1, no:0): ");
scanf("%d %d %d",&G->vexnum,&G->arcnum,&has_info); //输入顶点个数,边个数及是否有其他信息
printf("please input %d string of vertex value(<%d chars of each string):\n",G->vexnum,MAX_NAME);
for(i = 0;i < G->vexnum;++i) //依次输入顶点的值
scanf("%s",G->vertex[i]);
for(i = 0;i < G->vexnum;++i) //邻接矩阵置空
for(j = 0;j < G->vexnum;++j){
G->arcs[i][j].adj = 0;
G->arcs[i][j].info = NULL;
}
printf("please input vertex1 vertex2 of the %d edges in order: \n",G->arcnum);
for(k = 0;k < G->arcnum;++k){
printf("%d 's edge:\n",k + 1);
scanf("%s %s",va,vb);
i = locate_vertex(G,va);
j