实验四 图的操作
图的生成,图的遍历。
2. 掌握有关图的操作算法并用高级语言编程实现;
3.熟练掌握图的两种搜索路径的遍历方法。
三、实验题目
本实验要求实现以下功能:
1.以邻接矩阵或邻接表作为存储结构建立一个无向图。
2.深度(或广度)优先搜索该无向图,输出遍历序列。
[测试数据]:对如图的无向图建立存储并遍历:
四、实验报告
1.实验题目。
2.程序中使用的数据结构及符号说明。
3.打印一份源程序并附上注释。
4.打印程序运行时的初值和运行结果,画出该无向图的形态,写出其邻接矩阵或邻接表。
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX_NUM 20 //最大顶点数
typedef char Vextype[2]; //顶点类型
int visited[MAX_VERTEX_NUM]={0}; //标志向量
typedef struct ArcNode //边结点定义
{
int adjvex; //邻接点域
struct ArcNode *next; //指向下一个边结点的指针域
}EdgeNode;
typedef struct vnode //表头结点定义
{
Vextype vertex; //顶点信息
EdgeNode *firstedge;
}VertexNode;
typedef struct //图的邻接表存储
{
VertexNode adjlist[MAX_VERTEX_NUM];
int R[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
int vexnum,arcnum; //顶点数和边数
}ALGraph;
typedef struct//定义队列
{
int V[MAX_VERTEX_NUM];
int front;
int rear;
}Queue;
void Initqueue(Queue *q)//初始化队列
{
q->front=0;
q->rear=0;
}
int Quempty(Queue *q)//判断队列是否为空
{
if(q->front==q->rear)
{
return 0;
}
else
{
return 1;
}
}
int Enqueue(Queue *q,int e)//入队操作
{
if((q->rear+1)%MAX_VERTEX_NUM==q->front)
{
printf("The queue is overflow!/n");
return 0;
}
else
{
q->V[q->rear]=e;
q->rear=(q->rear+1)%MAX_VERTEX_NUM;
return 1;
}
}
int Dequeue(Queue *q)//出队操作
{
int t;
if(q->front==q->rear)
{
printf("The queue is empty!/n");
return 0;
}
else
{
t=q->V[q->front];
q->front=(q->front+1)%MAX_VERTEX_NUM;
return t;
}
}
void creatgraph(ALGraph *g,int n)//创建图
{
int i,j,r1,r2;
g->vexnum=n;
printf("请输入顶点信息(空格间开):/n");
for(i=1;i<=n;i++)
{
scanf("%s",&(g->adjlist[i].vertex));
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
g->R[i][j]=0;
}
printf("请输入边的信息(空格间开,以0 0结束):/n");
scanf("%d%d",&r1,&r2);
while(r1!=0&&r2!=0)
{
g->R[r1][r2]=1;
g->R[r2][r1]=1;
scanf("%d%d",&r1,&r2);
}
}
void printgraph(ALGraph *g)//打印图的邻接矩阵
{
int i,j;
for(i=1;i<=g->vexnum;i++)
{
for(j=1;j<=g->vexnum;j++)
{
printf("%2d ",g->R[i][j]);
}
printf("/n");
}
}
int firstadjvex(ALGraph *g,int vex)//获取第一个未被访问的邻接节点
{
int w,i;
for(i=1;i<=g->vexnum;i++)
{
if(g->R[vex][i]==1&&visited[i]==0)
{
w=i;
break;
}
else
{
w=0;
}
}
return w;
}
int nextadjvex(ALGraph *g,int vex,int w)//获取下一个未被访问的邻接节点
{
int t;
t=firstadjvex(g,w);
return t;
}
void DFS(ALGraph *g,int vex)//深度递归遍历
{
int w;
visited[vex]=1;
printf("->%s",g->adjlist[vex].vertex);
for(w=firstadjvex(g,vex);w>0;w=nextadjvex(g,vex,w))
if(!visited[w])
{
DFS(g,w);
}
}
void DFSTraverse(ALGraph *g)//深度遍历
{
int i;
for(i=1;i<=g->vexnum;i++)
visited[i]=0;
for(i=1;i<=g->vexnum;i++)
if(!visited[i])
{
DFS(g,i);
}
}
void BFSTraverse(ALGraph *g)//广度遍历
{
int i;
Queue *q=(Queue *)malloc(sizeof(Queue));
for(i=1;i<=g->vexnum;i++)
{
visited[i]=0;
}
Initqueue(q);
for(i=1;i<=g->vexnum;i++)
{
if(!visited[i])
{
visited[i]=1;
printf("->%s",g->adjlist[i].vertex);
Enqueue(q,g->vexnum);
while(!Quempty(q))
{
int u,w;
u=Dequeue(q);
for(w=firstadjvex(g,u);w>0;w=nextadjvex(g,u,w))
{
if(!visited[w])
{
visited[w]=1;
printf("->%s",g->adjlist[w].vertex);
Enqueue(q,w);
}
}
}
}
}
}
void main()
{
int n;
ALGraph *g=(ALGraph *)malloc(sizeof(ALGraph));
printf("请输入顶点数:/n");
scanf("%d",&n);
creatgraph(g,n);
printf("邻接矩阵输出:/n");
printgraph(g);
printf("广度遍历:/n");
BFSTraverse(g);
printf("/n");
printf("深度遍历:/n");
DFSTraverse(g);
printf("/n");
}