图子系统
1.实验目的
(1)掌握图邻接矩阵的存储方法。
(2)掌握图深度优先遍历的基本思想。
(3)掌握图广度优先遍历的基本思想。
2.实验内容
(1)编写按键盘输入的数据建立图的邻接矩阵存储。
(2)编写图的深度优先遍历函数。
(3)编写图的广度优先遍历函数。
(4)设计一个选择式菜单如下:
图 子 系 统
**************************************************
* 1---------更新邻接矩阵 *
* 2---------深度优先遍历 *
* 3---------广度优先遍历 *
* 0---------退 出 *
**************************************************
请选择菜单号(0---3):
附C源程序如下:
#include <stdio.h>
#define GRAPHMAX 10
#define Queuesize 30
typedef struct
{ char vexs[GRAPHMAX];
int edges[GRAPHMAX][GRAPHMAX];
int n,e;
}MGraph;
int visited[10];
void CreateMGraph(MGraph *G);
void DFSTraverseM(MGraph *G);
void DFSM(MGraph *G,int i);
void BFSTraverseM(MGraph *G);
void BFSM(MGraph *G,int k);
typedef struct
{ int front;
int rear;
int count;
int data[Queuesize];
}CirQueue;
void InitQueue(CirQueue *Q)
{ Q->front=Q->rear=0;
Q->count=0;
}
int QueueEmpty(CirQueue *Q)
{
return Q->count==0;
}
int QueueFull(CirQueue *Q)
{
return Q->count==Queuesize;
}
void EnQueue(CirQueue *Q,int x)
{
if(QueueFull(Q))
printf("Error! Queue overflow.");
else
{ Q->count++;
Q->data[Q->rear]=x;
Q->rear=(Q->rear+1)%Queuesize;
}
}
int DeQueue(CirQueue *Q)
{ int temp;
if (QueueEmpty(Q))
{ printf("Error! Queue underflow.");
return NULL;
}
else
{ temp=Q->data[Q->front];
Q->count--;
Q->front=(Q->front+1)%Queuesize;
return temp;
}
}
void main()
{ MGraph *G,a; //定义a 为一个MGraph 类型结构变量,则 a 的存储单元就确定下来
char ch1;
int ch2;
G=&a;
printf("\n\t\t 建立一个图的邻接矩阵存储结构:\n");
CreateMGraph(G);
getchar();
ch1='y';
while (ch1=='y'|| ch1=='Y')
{
printf("\n");
printf("\n\t\t 图 子 系 统 ");
printf("\n\t\t**************************************************");
printf("\n\t\t* 1---------更新邻接矩阵 *");
printf("\n\t\t* 2---------深度优先遍历 *");
printf("\n\t\t* 3---------广度优先遍历 *");
printf("\n\t\t* 0---------退 出 *");
printf("\n\t\t**************************************************");
printf("\n\t\t 请选择菜单号(0---3): ");
scanf("%d",&ch2);
getchar();
switch(ch2)
{ case 1:
CreateMGraph(G);
printf("\n\t\t 图的邻接矩阵存储结构建立完毕.");
break;
case 2:
DFSTraverseM(G);
break;
case 3:
BFSTraverseM(G);
break;
case 0:
ch1='n';
break;
default:
printf("\n\t\t 输入错误!请重新输入 ");
}
}
}
void CreateMGraph(MGraph *G) //建立图的邻接矩阵存储
{ int i,j,k;
char ch1,ch2;
printf("\n\t\t 请输入顶点数,边数并按回车(格式如:3,4):");
scanf("%d,%d",&(G->n),&(G->e)); //输入顶点数,边数
for (i=0; i<G->n; i++) //输入各顶点符号
{
getchar();
printf("\n\t\t 请输入第 %d 个顶点并按回车: ",i+1);
scanf("%c", &(G->vexs[i]));
}
for(i=0; i<G->n; i++)
for(j=0; j<G->n; j++)
G->edges[i][j]=0;
for(k=0; k<G->e; k++)
{ getchar();
printf("\n\t\t 请输入第 %d 条边的顶点符号(格式为:顶点符号,顶点符号):",k+1);
scanf("%c,%c",&ch1,&ch2);
for(i=0;ch1!=G->vexs[i];i++);
for(j=0;ch2!=G->vexs[j];j++);
G->edges[i][j]=1;
}
printf("\n\t\t 已建立一个图的邻接矩阵存储结构!现输出此邻接矩阵如下:\n");
for(i=0; i<G->n; i++) //输出此邻接矩阵
{ printf("\n\t\t");
for(j=0; j<G->n; j++)
printf("%5d",G->edges[i][j]);
}
}
void DFSTraverseM(MGraph *G) //深度优先遍历
{ int i;
for(i=0; i<G->n; i++)
visited[i]=0;
for(i=0; i<G->n; i++)
if(!visited[i])
DFSM(G,i);
}
void DFSM(MGraph *G,int i)
{ int j;
printf("\n\t\t 深度优先遍历序列:%c\n", G->vexs[i]);
visited[i]=1;
for(j=0; j<G->n; j++)
if( G->edges[i][j]==1 && !visited[j])
DFSM(G,j); // 递归调用DFSM(),直到没有未被访问的相邻顶点,则访问后返回到上一层
}
void BFSTraverseM(MGraph *G)
{ int i;
for(i=0; i<G->n; i++)
visited[i]=0;
for(i=0; i<G->n; i++)
if(!visited[i])
BFSM(G,i);
}
void BFSM(MGraph *G, int k)
{ int i,j;
CirQueue Q; //定义 Q 为一个循环队列结构变量
InitQueue(&Q);
printf("\n\t\t 广度优先遍历序列: %c\n", G->vexs[k]); //访问此顶点
visited[k]=1; // 将该顶点的访问标志置为已访问
EnQueue(&Q,k); // 将该顶点的序号进对
while( !QueueEmpty(&Q) )
{ i=DeQueue(&Q); //已访问顶点的序号从对首出对
for(j=0; j<G->n; j++)
if( G->edges[i][j]==1 && !visited[j] ) //如果 j 是 i 的邻接点并且 j 未被访问过
{ printf("\n\t\t 广度优先遍历序列: %c\n", G->vexs[j]);
visited[j]=1;
EnQueue(&Q,j); // j 被访问后进对尾
}
}
}