实验报告内容:
一、实验目的、要求:
(1)熟练掌握图的二种存储结构的建立、图的深度优先搜索和广度优先搜索二种遍历方法。
(2)编写适当的主函数和相关函数,使实验题目运行出正确结果。
(3)当场编程、调试、编译。
(4)程序具有一定的健壮性、可读性,尽量简洁。
(5)程序运行完成后分别存盘,上交实验报告,要求写出实验体会
二、实验内容:
1、第一道题:
(1)实验题目
建立有向图的邻接矩阵存储结构,实现图的深度优先搜索算法。
(2)主要函数的设计思想
{
int w;
printf("->%c",G.vexs[v]);
visited[v]=TRUE;
for(w=0;w<G.vexnum;w++)
if((G.arcs[v][w]!=0)&&(!visited[w]))
DFS(G,w);
}
(3)程序清单
#include"stdio.h"
#include"stdlib.h"
#define MaxInt 32767
#define MAX_VEX 20 //最大顶点个数
typedef enum{
FALSE,TRUE} boolean;
typedef char VertexType;
typedef struct{
//图的邻接矩阵存储结构
VertexType vexs[MAX_VEX]; //顶点向量
int arcs[MAX_VEX][MAX_VEX]; //邻接矩阵
int vexnum,arcnum; //图的当前顶点数和弧数
}MGraph;
boolean visited[MAX_VEX]; //访问标志数组
//图G中查找元素c的位置
int Locate(MGraph G,char c){
for(int i=0;i<G.vexnum;i++)
if(G.vexs[i]==c) return i;
return -1;
}
//请输入以下创建有向图的邻接矩阵存储结构
void createVDN(MGraph &G){
int i,j,s1,s2;
char a,b,temp;
printf("输入定点数和弧数:");
scanf("%d%d",&G.vexnum,&G.arcnum);
temp=getchar();
printf("输入%d个顶点(以一个空格做间隔):\n",G.vexnum);
for(i=0;i<G.vexnum;i++)
{
scanf("%c",&G.vexs[i]);
temp=getchar();
}
for(i=0;i<G.vexnum;i++)
for(j=0;j<G.vexnum;j++)
G.arcs[i][j]=0;
printf("输入%d条弧(以空格做间隔):\n",G.arcnum);
for(i=0;i<G.arcnum;i++)
{
printf("输入弧%d: ",i+1);
scanf("%c %c",&a,&b);
temp=getchar();
s1=Locate(G,a);
s2=Locate(G,b);
G.arcs[s1][s2]-1;
}
}
void DFS(MGraph G,int v)
{
int w;
printf("->%c",G.vexs[v]);
visited[v]=TRUE;
for(w=0;w<G.vexnum;w++)
if((G.arcs[v][w]!=0)&&(!visited[w]))
DFS(G,w);
}
// 对非连通图 G 作深度优先遍历。
void DFSTraverse(MGraph G, int v) {
for (v=0; v<G.vexnum; ++v)
visited[v] = FALSE; // 访问标志数组初始化
for (v=0; v<G.vexnum; ++v)
if (!visited[v]) DFS(G, v); // 对尚未访问的顶点调用DFS
}
//主函数
int main()
{
MGraph G;
createVDN (G);
printf("深度优先遍历: ");
DFSTraverse (G,0);
printf("\n");
}
2、第二道题:
(1)实验题目
建立无向图的邻接矩阵存储结构,实现图的广度优先搜索算法。
(2)主要函数的设计思想
int NextVex(MGraph G,int i,int j){
if(i>=0 && i<G.vexnum && j>=0 && j<G.vexnum){
//i,j合理
for(int k=j+1;k<G.vexnum;k++)
if(G.arcs[i][k]!=0) return k;
}
return -1;
}
实验二:
#include"stdio.h"
#include"stdlib.h"
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define MaxInt 32767
#define MAX_VEX 20 //最大顶点个数
#define MAXQSIZE (MAX_VEX+1) //队列长度
typedef int Status;
typedef enum{
FALSE,TRUE} boolean;
typedef char VertexType;
typedef struct{
//图的邻接矩阵存储结构
VertexType vexs[MAX_VEX]; //顶点向量
int arcs[MAX_VEX][MAX_VEX]; //邻接矩阵
int vexnum,arcnum; //图的当前顶点数和弧数
}MGraph;
boolean visited[MAX_VEX]; //访问标志数组
//----- 队列的顺序存储表示 -----
typedef int QElemType;
typedef struct {
QElemType *base;
int front;
int rear;
} SqQueue;
// 构造一个空队列Q
Status InitQueue(SqQueue &Q){
Q.base=(QElemType*)malloc(MAXQSIZE*sizeof(QElemType));
if(!Q.base)exit(OVERFLOW);
Q.front=Q.rear=0;
return OK;
}
//判队列是否为空
Status QueueEmpty (SqQueue Q) {
if(Q.rear==Q.front) return OK;
else return ERROR ;
}
//入队函数
Status EnQueue (SqQueue &Q, QElemType e) {
if((Q.rear+1)%MAXQSIZE==Q.front) return ERROR;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE;
return OK;
}
//出队函数
Status DeQueue (SqQueue &Q, QElemType &e) {
if(Q.rear==Q.front) return ERROR;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
return OK;
}
//图G中查找元素c的位置
int Locate(MGraph G,char c){
for(int i=0;i<G.vexnum;i++)
if(G.vexs[i]==c) return i;
return -1;
}
//创建无向图的邻接矩阵存储结构
void CreateUDN(MGraph &G){
int i,j,s1,s2;
char a,b,temp;
printf("输入顶点数和弧数:");
scanf("%d%d",&G.vexnum,&G.arcnum);
temp=getchar(); //接收回车
printf("输入%d个顶点(以一个空格做间隔):\n",G.vexnum);
for(i=0;i<G.vexnum;i++){
//初始化顶点
scanf("%c",&G.vexs[i]);
temp=getchar(); //接收回车
}
for(i=0;i<G.vexnum;i++) //初始化邻接矩阵
for(j=0;j<G.vexnum;j++)
G.arcs[i][j]=0; //初始化弧
printf("输入%d条弧(以空格做间隔):\n",G.arcnum);
for(i=0;i<G.arcnum;i++){
printf("输入弧%d: ",i+1);
scanf("%c %c",&a,&b); //输入一条边依附的顶点
temp=getchar(); //接收回车
s1=Locate(G,a);
s2=Locate(G,b);
G.arcs[s1][s2]=G.arcs[s2][s1] =1;
}
}
//图G中顶点k的第一个邻接顶点
int FirstVex(MGraph G,int k){
if(k>=0 && k<G.vexnum){
//k合理
for(int i=0;i<G.vexnum;i++)
if(G.arcs[k][i]!=0) return i;
}
return -1;
}
//图G中顶点i的第j个邻接顶点的下一个邻接顶点
int NextVex(MGraph G,int i,int j){
if(i>=0 && i<G.vexnum && j>=0 && j<G.vexnum){
//i,j合理
for(int k=j+1;k<G.vexnum;k++)
if(G.arcs[i][k]!=0) return k;
}
return -1;
}
//请输入以下对连通图G广度优先遍历的算法
//广度优先遍历
void BFS(MGraph G){
int k;
SqQueue Q; //辅助队列Q
InitQueue(Q);
for(int v=0;v<G.vexnum;v++)
visited[v]=FALSE;
for(int i=0;i<G.vexnum;i++)
if(!visited[i]){
//i尚未访问
visited[i]=TRUE;
printf("%c",G.vexs[i]);
EnQueue(Q,i); //i入列
while(Q.front!=Q.rear){
DeQueue(Q,k); //队头元素出列并置为k
for(int w=FirstVex(G,k);w>=0;w=NextVex(G,k,w))
if(!visited[w])
{
//w为k的尚未访问的邻接顶点
visited[w]=TRUE;
printf("->%c",G.vexs[w]);
EnQueue(Q,w);
}
}
}
}
//主函数
int main()
{
MGraph G;
CreateUDN(G);
printf("广深度优先遍历: ");
BFS(G);
printf("\n");
}