图的邻接矩阵存储结构形式:
#define INFINITY 0
#define MAX_VERTEX_NUM 20
typedef enum{DG=1,DN,UDG,UDN}GraphKind;//{有向图,有向网,无向图,无向网},枚举类型
typedef struct{
VertexType vexs[MAX_VERTEX_NUM];//顶点的值
int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//邻接矩阵 ,边表
int vexnum,arcnum;//顶点数,边数
GraphKind kind;//选择图的类型
}MGraph;
注:该结构体没有定义结构体指针,所以在引用该结构体的成员时需要注意用"."还是使用"->"引用结构体成员。
如果你使用的变量x是个结构体,应该用.访问其成员,如:x.num
如果你使用的变量x是个结构体指针,应该用->访问其成员,如:x->num
如果当前变量x是个结构体而你却使用了x->num的方式访问,就属会出现上面的报错。
创建图
void CreateMGraph(MGraph *G){
int i,j,k,w;
printf("请输入顶点数和边数:\n");
scanf("%d%d",&G->vexnum,&G->arcnum);
//确定图的类型
printf("请输入图的类型:");
scanf("%d",&G->kind); //输入数字
fflush(stdin);//清空缓冲区
//创建顶点表,值为字符
for(i=0;i<G->vexnum;i++){
printf("请输入第%d个顶点:",i+1);
scanf("%c",&G->vexs[i]);
getchar();//消除回车键
}
// 初始化边表,并且当边不存在时arcs[i][j]=0
for(i=0;i<G->vexnum;i++){
for(j=0;j<G->vexnum;j++){
G->arcs[i][j]=INFINITY;
}
}
//创建边表
for(k=0;k<G->arcnum;k++){
printf("请输入边<Vi,Vj>的下标i,j和权w(空格分开):");
scanf("%d%d%d",&i,&j,&w);
G->arcs[i][j]=w;
if(G->kind==3)G->arcs[j][i]=G->arcs[i][j];//若为无向图
}
}
选择图类型时是输入数字,整型1、2、3、4依次表示 有向图,有向网,无向图,无向网。
输出邻接矩阵
void OutMGraph(MGraph G){
int i,j,count=0;
printf("\t");
for(i=0;i<G.vexnum;i++)printf("\t%c",G.vexs[i]);
printf("\n");
for(i=0;i<G.vexnum;i++){
printf("\t%c",G.vexs[i]);
for(j=0;j<G.vexnum;j++){
printf("\t%d",G.arcs[i][j]);
count++;
if(count%G.vexnum==0)printf("\n");
}
}
}
void CreateMGraph(MGraph *G)函数中的形参是指针类型,所以在应用结构体的成员时需使用"->";
函数void OutMGraph(MGraph G)中的形参结构体类型,在引用结构体的成员时使用"."。
深度优先搜索
//深度优先递归算法
void DFS(MGraph G,int i)
{
int j;
visited[i]=TRUE; //被访问的标记
printf("%c->",G.vexs[i]);
for(j=0;j<G.vexnum;j++)
{
if(G.arcs[i][j]&&!visited[j]) //边(i,j)存在且j顶点未被访问,递归
DFS(G,j);
}
}
//深度优先遍历
void DFStraverse(MGraph G)
{
int i;
for(i=0;i<G.vexnum;i++)
visited[i]=FALSE;//全部遍历顶点没被访问
for(i=0;i<G.vexnum;i++)
if(!visited[i])DFS(G,i);
};
完整代码
文件后缀为".cpp"
#include<stdio.h>
#include<stdlib.h>
#define INFINITY 0
#define MAX_VERTEX_NUM 20
#define OK 1
#define TRUE 1
#define FALSE 0
typedef char VertexType;
typedef int Boole; //布尔类型 存储TRUE FALSE
Boole visited[MAX_VERTEX_NUM]; //访问标志数组
typedef enum{DG=1,DN,UDG,UDN}GraphKind;//{有向图,有向网,无向图,无向网},枚举类型
typedef struct{
VertexType vexs[MAX_VERTEX_NUM];//顶点的值
int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//邻接矩阵 ,边表
int vexnum,arcnum;//顶点数,边数
GraphKind kind;
}MGraph;
//创建有向图,无向图
void CreateMGraph(MGraph *G){
int i,j,k,w;
printf("请输入顶点数和边数:\n");
scanf("%d%d",&G->vexnum,&G->arcnum);
//确定图的类型
printf("请输入图的类型:");
scanf("%d",&G->kind); //输入数字
fflush(stdin);//清空缓冲区
//创建顶点表,值为字符
for(i=0;i<G->vexnum;i++){
printf("请输入第%d个顶点:",i+1);
scanf("%c",&G->vexs[i]);
getchar();//消除回车键
}
// 初始化边表,并且当边不存在时arcs[i][j]=0
for(i=0;i<G->vexnum;i++){
for(j=0;j<G->vexnum;j++){
G->arcs[i][j]=INFINITY;
}
}
//创建边表
for(k=0;k<G->arcnum;k++){
printf("请输入边<Vi,Vj>的下标i,j和权w(空格分开):");
scanf("%d%d%d",&i,&j,&w);
G->arcs[i][j]=w;
if(G->kind==3)G->arcs[j][i]=G->arcs[i][j];//若为无向图
}
}
//输出邻接矩阵
void OutMGraph(MGraph G){
int i,j,count=0;
printf("\t");
for(i=0;i<G.vexnum;i++)printf("\t%c",G.vexs[i]);
printf("\n");
for(i=0;i<G.vexnum;i++){
printf("\t%c",G.vexs[i]);
for(j=0;j<G.vexnum;j++){
printf("\t%d",G.arcs[i][j]);
count++;
if(count%G.vexnum==0)printf("\n");
}
}
}
//深度优先递归算法
void DFS(MGraph G,int i)
{
int j;
visited[i]=TRUE; //被访问的标记
printf("%c->",G.vexs[i]);
for(j=0;j<G.vexnum;j++)
{
if(G.arcs[i][j]&&!visited[j]) //边(i,j)存在且j顶点未被访问,递归
DFS(G,j);
}
}
//深度优先遍历
void DFStraverse(MGraph G)
{
int i;
for(i=0;i<G.vexnum;i++)
visited[i]=FALSE;//全部遍历顶点没被访问
for(i=0;i<G.vexnum;i++)
if(!visited[i])DFS(G,i);
};
int main(){
MGraph G;
int i,j;
CreateMGraph(&G);
printf("邻接矩阵数据如下:\n");
OutMGraph(G);
DFStraverse(G);
printf("\n图遍历完毕");
return OK;
}
运行结果