1.实验目的
(1)掌握图的结构特性,各种存储结构及其适用范围;
(2)掌握图的创建及遍历算法。
(3)能够使用图解决实际问题,计算最小代价生成树
2.基本内容:
算法1:输入图的类型、顶点数、狐(边)数、顶点信息、狐(边)信息,建立相应的图(具体类型可以是无向图、有向图、无向网、有向网,采用邻接矩阵存储结构);分别按深度优先搜索和广度优先搜索遍历图;按某种形式输出图及遍历结果。
3.代码实现
cs
#include <stdio.h>
#define N 20 /*图中顶点数目的最大值为N*/
#define TRUE 1
#define FALSE 0
int visited[N]; /*访问标识数组*/
typedef struct /*队列的定义*/
{
int data[N];
int front,rear;
}queue;
typedef struct /*定义图的邻接矩阵*/
{
int vexnum,arcnum; //图中顶点数目、边/弧的数目
char vexs[N]; //一维数组:存储顶点信息
int arcs[N][N]; //二维数组:存储顶点与顶点之间的关系
}graph;
void createGraph(graph *g); /*建立一个无向图的邻接矩阵*/
void dfs(int i,graph *g); /*从第i个顶点出发进行深度优先搜索*/
void tdfs(graph *g); /*深度优先搜索整个图*/
void bfs(int k,graph *g); /*从第k个顶点出发进行广度优先搜索*/
void tbfs(graph *g); /*广度优先搜索整个图*/
void init_visit(); /*初始化访问标识数组*/
//1.建立一个无向图的邻接矩阵
void createGraph(graph *g) /*建立一个无向图的邻接矩阵*/
{
int i,j;
char v;
g->vexnum = 0;
g->arcnum = 0;
i=0;
printf("输入顶点序列(以#结束):\n");
while((v=getchar()) != '#')
{
g->vexs[i] = v; /*读入顶点信息*/
i++;
}
g->vexnum = i; /*顶点数目*/
for(i=0;i<g->vexnum;i++)
{ /*邻接矩阵初始化*/
for(j=0;j<g->vexnum;j++)
{
g->arcs[i][j] = 0;
}
}
printf("输入边的信息(以-1,...结束):\n");
scanf("%d,%d",&i,&j); /*读入边i,j*/
while(i != -1) /*读入i,j为-1时结束*/
{
g->arcs[i][j] = 1;
g->arcs[j][i] = 1;
scanf("%d,%d",&i,&j);
}
}
//2.从第i个顶点出发进行深度优先搜索
void dfs(int i,graph *g) /*从第i个顶点出发进行深度优先搜索*/
{
int j;
printf("%c",g->vexs[i]);
visited[i] = TRUE;
for(j=0;j<g->vexnum;j++)
{
if((g->arcs[i][j]==1) && (!visited[j]))
{
dfs(j,g);
} //若第j个顶点与第i个顶点邻接且未被访问,则访问该顶点
}
}
//3.深度优先搜索整个图
void tdfs(graph *g) /*从图中各个顶点开始深度优先搜索整个图*/
{
int i;
for(i=0;i<g->vexnum;i++)
{
if(visited[i] != TRUE)
{
printf("\n从顶点%c开始深度优先搜索序列:",g->vexs[i]);
dfs(i,g);
printf("\n");
}
init_visit(); //每一轮遍历完成后需要初始化访问标识数组
}
}
//4.从第k个顶点出发进行广度优先搜索
void bfs(int k,graph *g) /*从第k个顶点出发进行广度优先搜索*/
{
int i,j;
queue qlist;
queue *q;
q = &qlist;
q->rear = 0;
q->front = 0;
printf("%c",g->vexs[k]); //访问第k个顶点
visited[k] = TRUE;
q->data[q->rear] = k; //第k个顶点入队(这里是将顶点下标k入队)
q->rear = (q->rear+1)%N;
while(q->rear != q->front) //队列非空时
{
i = q->data[q->front]; //队头元素出队
q->front = (q->front+1)%N;
//访问出队顶点所有相邻接、未被访问过的顶点。并在访问后将其入队
for(j=0;j<g->vexnum;j++)
{
if((g->arcs[i][j]==1) && (!visited[j]))
{
printf("%c",g->vexs[j]);
visited[j] = TRUE;
q->data[q->rear] = j;
q->rear =( q->rear+1)%N;
}
}
}
}
//5.广度优先搜索整个图
void tbfs(graph *g) /*广度优先搜索整个图*/
{
int i;
printf("\n从顶点%c开始广度优先搜索序列:",g->vexs[0]);
for(i=0;i<g->vexnum;i++)
{
if(visited[i] != TRUE)
{
bfs(i,g);
}
}
}
//6.初始化访问标识数组
void init_visit() /*初始化访问标识数组*/
{
int i;
for(i=0;i<N;i++)
{
visited[i] = FALSE;
}
}
int main()
{
graph ga;
int i,j;
createGraph(&ga);
printf("无向图的邻接矩阵:\n");
for(i=0;i<ga.vexnum;i++)
{
for(j=0;j<ga.vexnum;j++)
{
printf("%3d",ga.arcs[i][j]);
}
printf("\n");
}
init_visit();
tdfs(&ga);
init_visit();
tbfs(&ga);
printf("实验结束!\n");
return 0;
}