#include<stdio.h>
#define MAX_VERTEX_NUM 20
#define INFINITY 65535
#define UNVISITED 0
#define VISITED 1
typedef struct
{
char vexs[MAX_VERTEX_NUM];//储存顶点
int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//用于储存权值
int vernum,arcnum;//vernum表示结点个数,arcnum用来表示弧的个数
}MGraph;
//队列基本操作
typedef struct node
{
int data[MAX_VERTEX_NUM];
int front,rear;
}Queue;
void Init(Queue &q)//队列初始化
{
q.front=q.rear=0;
}
int InQueue(Queue &q,int n)//进队
{
if((q.rear+1)%MAX_VERTEX_NUM==q.front)
return 0;
q.data[q.rear]=n;
q.rear=(q.rear+1)%MAX_VERTEX_NUM;
return 1;
}
int Empty(Queue q)//判断队是否为空
{
if(q.front==q.rear)
return 1;
else
return 0;
}
int DelQueue(Queue &q,int &n)//出队
{
if(q.front==q.rear)
return 0;
n=q.data[q.front];
q.front=(q.front+1)%MAX_VERTEX_NUM;
return 1;
}
void CreateMGraph(MGraph &g)//创建邻接矩阵
{
int i,j,k;
int weight;
char v1,v2;
printf("请输入结点数及共有的弧长数:");
scanf("%d%d",&g.vernum,&g.arcnum);//输入节点数及边数
for(i=0;i<g.vernum;i++)//初始化
{
for(j=0;j<g.vernum;j++)
{
if(i==j)
g.arcs[i][j]=0;
else
g.arcs[i][j]=INFINITY;
}
}
for(i=0;i<g.vernum;i++)
{
getchar();
printf("请输入第%d个顶点的信息:",i+1);//输入邻接矩阵的各个顶点元素
scanf("%c",&g.vexs[i]);
}
printf("\n");
for(k=0;k<g.arcnum;k++)
{
getchar();
printf("请输入边的信息(顶点-顶点-权值):");//边对应的顶点及权值
scanf("%c %c %d",&v1,&v2,&weight);
for(i=0;i<g.vernum;i++)
{
if(g.vexs[i]==v1)
break;
}
for(j=0;j<g.vernum;j++)
{
if(g.vexs[j]==v2)
break;
}
g.arcs[i][j]=weight;
g.arcs[j][i]=weight;
}
}
void ShowGraph(MGraph g) //将生成的邻接矩阵打印出来
{
int i,j;
printf("\n邻接矩阵为:\n");
printf("\t");
for(i=0;i<g.vernum;i++)
{
printf("%6c",g.vexs[i]);
}
for(i=0;i<g.vernum;i++)
{
printf("\n%8c",g.vexs[i]);
for(j=0;j<g.vernum;j++)
{
if(g.arcs[i][j]==INFINITY)
printf("%6s","∞");
else
printf("%6d",g.arcs[i][j]);
}
printf("\n");
}
}
void Insert(MGraph &g,char v1,char v2,int weight) //插入边的操作
{
int i,j;
for(i=0;i<g.vernum;i++)
{
if(g.vexs[i]==v1)
break;
}
for(j=0;j<g.vernum;j++)
{
if(g.vexs[j]==v2)
break;
}
g.arcs[i][j]=weight;
g.arcs[j][i]=weight;
}
void Delete(MGraph &g,char v1,char v2) //删除边的操作
{
int i,j;
for(i=0;i<g.vernum;i++)
{
if(g.vexs[i]==v1)
break;
}
for(j=0;j<g.vernum;j++)
{
if(g.vexs[j]==v2)
break;
}
g.arcs[i][j]=INFINITY;
g.arcs[j][i]=INFINITY;
}
int visited[MAX_VERTEX_NUM]; //将访问过的元素置VISITED
void DFS(MGraph g,int v) //深度搜索
{
int i;
visited[v]=1;
printf("%c ",g.vexs[v]);
for(i=0;i<g.vernum;i++)
{
if(visited[i]==UNVISITED&&g.arcs[v][i]!=0&&g.arcs[v][i]!=INFINITY)
{
DFS(g,i); //递归
}
}
}
void DFSTraverse(MGraph g)
{
int v;
for(v=0;v<g.vernum;v++)
{
visited[v]=UNVISITED; //矩阵初始化
}
for(v=0;v<g.vernum;v++)
{
if(visited[v]==UNVISITED)
DFS(g,v);
}
}
void BFS(MGraph g) //广度搜索
{
int visit[MAX_VERTEX_NUM];
int i,j,u;
Queue q;
Init(q);
for(i=0;i<g.vernum;i++)
{
visit[i]=UNVISITED;
}
for(i=0;i<g.vernum;i++)
{
if(visit[i]==UNVISITED)
{
printf("%c",g.vexs[i]);
visit[i]=VISITED; //将访问的元素进队
InQueue(q,i);
while(!Empty(q))
{
DelQueue(q,u);
for(j=0;j<g.vernum;j++)
{
if(g.arcs[u][j]!=0&&g.arcs[u][j]!=INFINITY&&visit[j]==UNVISITED)
{
printf("%c",g.vexs[j]);
visit[j]=VISITED;
InQueue(q,i);
}
}
}
}
}
}
void main()
{
int num;
MGraph g;
char v1,v2,weight;
printf("|1-创建\n");
printf("|2-进行插入边的操作\n");
printf("|3-进行删除边的操作\n");
printf("|4-深度搜索\n");
printf("|5-广度搜索\n");
printf("|6-打印邻接矩阵\n");
printf("\n请输入想要进行的操作:");
while(1)
{
scanf("%d",&num);
switch(num)
{
case 1:
CreateMGraph(g);//创建
break;
case 2:
getchar();
printf("输入想要插入的信息(顶点-顶点-边):");//进行插入边的操作
scanf("%c %c %d",&v1,&v2,&weight);
Insert(g,v1,v2,weight);
break;
case 3:
getchar();
printf("输入想要删除的信息(顶点-顶点):");//进行删除边的操作
scanf("%c %c",&v1,&v2);
Delete(g,v1,v2);
break;
case 4:
DFSTraverse(g); //深度搜索
break;
case 5:
BFS(g); //广度搜索
break;
case 6:
ShowGraph(g);//显示邻接矩阵
break;
}
}
}
遇到问题:1.scanf输入字符型前面需要加入getchar();用来清空缓冲区中的回车符
2.代码中有\t,可用于对齐。
3.深度优先搜索必须用队列,其他捷径应该是没有的。
4.广度搜索还应该再多体会一下,以后比赛应该经常用到。
建立一个包含6个结点的无向图的邻接矩阵,实现插入、删除边的功能,并进行深度优先遍历和广度优先遍历。
最新推荐文章于 2023-08-27 00:01:31 发布