实验项目
图的遍历操作
实验目的
掌握有向图和无向图的概念;掌握邻接矩阵和邻接链表建立图的存储结构;掌握DFS及BFS对图的遍历操作;了解图结构在人工智能、工程等领域的广泛应用。
实验内容
采用邻接矩阵和邻接链表其中一种作为图的存储结构,完成有向图和无向图的DFS和BFS操作。
(一)数据结构的定义
图遍历又称图的遍历,属于数据结构中的内容。指的是从图中的任一顶点出发,对图中的所有顶点访问一次且只访问一次。图的遍历操作和树的遍历操作功能相似。图的遍历是图的一种基本操作,图的许多其它操作都是建立在遍历操作的基础之上。
由于图结构本身的复杂性,所以图的遍历操作也较复杂,主要表现在以下四个方面:
① 在图结构中,没有一个“自然”的首结点,图中任意一个顶点都可作为第一个被访问的结点。
② 在非连通图中,从一个顶点出发,只能够访问它所在的连通分量上的所有顶点,因此,还需考虑如何选取下一个出发点以访问图中其余的连通分量。
③ 在图结构中,如果有回路存在,那么一个顶点被访问之后,有可能沿回路又回到该顶点。
④ 在图结构中,一个顶点可以和其它多个顶点相连,当这样的顶点访问过后,存在如何选取下一个要访问的顶点的问题。
图的存储结构定义为邻接矩阵:
/*定义图存储结构*/
#define maxn 500 // 图中顶点数
#define maxe 1000 // 图中边数
typedef struct{
int v[maxn+1]; // 存放顶点信息
int arcs[maxn+1][maxn+1]; // 邻接矩阵
}graph;
(二)总体设计
实验总共包括六个函数:主函数,无向图的建立函数,有向图的建立函数,DFS遍历函数,BFS遍历算法函数,打印邻接矩阵函数。
主函数:统筹调用各个函数以实现相应功能
Int main()
void execute()
无向图的建立函数:建立无向图的邻接矩阵
void creatadi(graph &g,int n,int e)
有向图的建立函数:建立有向图的邻接矩阵
void creatadj(graph &g,int n,int e)
DFS遍历函数:利用深度优先遍历图的方法遍历图
void DFS1(int cur,graph &g,int n)
BFS遍历函数:利用广度优先遍历图的方法遍历图
void BFS1(graph &g,int n)
打印邻接矩阵函数:利用遍历邻接矩阵的方法打印图
void printArr(graph &g,int n,int e)
(三)各函数的详细设计:
主函数main()
主要就是进行功能的实现。
无向图的建立函数void creatadi(graph &g,int n,int e):
建立无向图的邻接矩阵,由于无向图是对称的,所以邻接矩阵是对称的。
有向图的建立函数void creatadj(graph &g,int n,int e):
建立有向图的邻接矩阵,由于有向图是单边的,所以邻接矩阵是不对称的。
DFS遍历函数void DFS1(int cur,graph &g,int n) :
利用深度优先遍历图的方法遍历图,主要是通过递归来一个一个顶点找过去,走过的标记一下,没路了在回去找。
BFS遍历函数void BFS1(graph &g,int n):
利用广度优先遍历图的方法遍历图,主要运用了队列的结构,将与该顶点有联系的都放进队列,之后再把队列里面的值打印出来。
打印邻接矩阵函数void printArr(graph &g,int n,int e):
利用遍历邻接矩阵的方法打印图
实验测试结果
无向图建立以及结果:
有限图创建以及结果:
实验总结:(100字到200字)
此部分附上主要程序代码和相关的注释说明、调试数据及过程、问题及解决办法。 (最重要)
(1)调试过程中主要遇到哪些问题?是如何解决的?
答:在建立图的存储结构的时候还是遇见过一些问题的,数组开的太大,导致程序无法运行,还有就是图的遍历这一块地方,BFS这个通过队列来放数据时,出现过一点小问题,不过问题不是很大,能够自己解决。
(2)经验和体会
答:还是那句老话,多敲代码自己练习,有时间把多复习多上网查查资料,增加自己对图的遍历的理解。
附录 实验程序代码(该部分请加注释)
/picture.h函数代码/
#define maxn 500 // 图中顶点数
#define maxe 1000 // 图中边数
typedef struct{
int v[maxn+1]; // 存放顶点信息
int arcs[maxn+1][maxn+1]; // 邻接矩阵
}graph;
//无向图的邻接矩阵
void creatadi(graph &g,int n,int e)
{
int i, j, k;
for (i=1; i<=n; i++ )
for (j=1; j<=n; j++)
g.arcs[i][j]=0;
for (k=1; k<=e; k++)
{
std::cout<<"第"<>i>>j; //输入一条边(i,j)
g.arcs[i][j] = 1;
g.arcs[j][i] = 1;
}
}
//有向图的邻接矩阵
void creatadj(graph &g,int n,int e)
{
int i, j, k;
for (i=1; i<=n; i++ )
for (j=1; j<=n; j++)
g.arcs[i][j] = 0;
for (k=1; k<=e; k++)
{
std::cout<<"第"<>i>>j; //输入一条弧
g.arcs[i][j] = 1;
}
}
void printArr(graph &g,int n,int e){
int i,j;
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
cout< n){
break;
}
}
head++;
}
for(i=1;i<=n;i++)
std::cout<
/menu.h菜单函数代码/
void menu(){
std::cout<<"\n";
std::cout<<" ************************图的应用************************\n";
std::cout<<" * *\n";
std::cout<<" * a:创建无向图的邻接矩阵 b:创建有向图的邻接矩阵 *\n";
std::cout<<" * c:DFS遍历 d:BFS遍历 *\n";
std::cout<<" * g:退出程序 *\n";
std::cout<<" * *\n";
std::cout<<" ********************************************************\n";
}
/主函数代码/
#include
using namespace std;
int sum = 0,que[10001];
#include "menu.h"
#include "picture.h"
int main()
{
void execute();
execute();
return 0;
}
void execute()
{
for(;;)
{
menu();
graph s;
char a;
int n,e;
cin>>a;
switch(a)
{
case 'a':
cout<<"请输入顶点个数:"<>n;
cout<<"请输入边的个数:"<>e;
creatadi(s,n,e);
printArr(s,n,e);
break;
case 'b':
cout<<"请输入顶点个数:"<>n;
cout<<"请输入边的个数:"<>e;
creatadj(s,n,e);
printArr(s,n,e);
break;
case 'c':
cout<<"该图DFS遍历为:"<