课程名称:数据结构
实验项目名称:图结构基本操作的实现
实验目的:
1.掌握图的基本操作—遍历。
实验要求:
1、 分别用DFS和BFS的方法实现一个无向图的遍历。
实验过程:
1、 创建一个图(可用邻接矩阵或邻接表的方式进行存储);
2、 输入选项:0或1,0为DFS,1为BFS。
3、 分别输出DFS和BFS两种遍历序列;
实验报告中给出DFS和BFS两种遍历的算法代码。
实验结果:
1、输入顶点集:1 2 3 4 5 6 7 8
2、输入边的集合: 1 2
1 3
2 4
2 5
4 8
5 8
3 6
3 7
6 7
输入:0(DFS)
输出:DFS遍历序列为:12485367
输入:1(BFS)
输出:BFS遍历序列为:12345678
实验分析:
1.简单分析DFS与BFS实现时用到的方法(DFS通过递归函数实现,用到栈的数据结构,BFS用到队列的数据结构);
2.列举调试运行过程中出现的错误并分析原因。
要求:
(1) 程序要添加适当的注释,程序的书写要采用缩进格式。
(2) 程序要具在一定的健壮性,即当输入数据非法时,程序也能适当地做出反应。
(3) 程序要做到界面友好,在程序运行时用户可以根据相应的提示信息进行操作。
(4) 上传源程序到课堂派。顺序表的源程序保存为TraversalGraph.cpp。
#include<iostream>
using namespace std;
#define MaxInt 32767
#define MVNum 100
#define true 1
#define OK 1
#define MAXQSIZE 100
#define OVERFLOW -1
#define ERROR 0
typedef int Status;
typedef char VerTexType;
typedef int ArcType;
typedef struct
{
int* base;
int front;
int rear;
}SqQueue;
typedef struct
{
VerTexType vexs[MVNum];
ArcType arcs[MVNum][MVNum];
int vexnum, arcnum;
} AMGraph;
Status InitQueue(SqQueue& Q)
{//构造一个空队列Q
Q.base = new int[MAXQSIZE];
if (!Q.base) exit(OVERFLOW);
Q.front = Q.rear = 0;
return OK;
}
Status EnQueue(SqQueue& Q, int e)
{//插入元素e为Q的新的队列元素
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, int& e)
{//删除Q的队头元素,用e返回其值
if (Q.front == Q.rear) return ERROR;
e = Q.base[Q.front];
Q.front = (Q.front + 1) % MAXQSIZE;
return OK;
}
Status QueueEmpty(SqQueue Q)
{
if (Q.front == Q.rear)
return OK;
return ERROR;
}
Status LocateVex(AMGraph G, VerTexType v)
{
int i;
for (i = 0; i < MVNum; i++)
{
if (G.vexs[i] == v)
return i;
}
}
Status CreateUDN(AMGraph& G)
{//采用邻接矩阵表示法,创建无向网G
puts("请输入点数和边数:");
cin >> G.vexnum >> G.arcnum;
puts("请输入顶点集:");
for (int i = 0; i < G.vexnum; ++i)
cin >> G.vexs[i];
for (int i = 0; i < G.vexnum; ++i)
for (int j = 0; j < G.vexnum; ++j)
G.arcs[i][j] = MaxInt;
puts("请输入边的集合:");
VerTexType v1, v2;
int i, j;
for (int k = 0; k < G.arcnum; ++k)
{
cin >> v1 >> v2;
i = LocateVex(G, v1);
j = LocateVex(G, v2);
G.arcs[i][j] = 1;
G.arcs[j][i] = G.arcs[i][j];
}
return OK;
}
int FirstAdjVex(AMGraph G, int v)
{
for (int i = 0; i < G.vexnum; i++)
{
if (G.arcs[v][i] != MaxInt)
{
return i;
}
}
return -1;
}
int NextAdjVex(AMGraph G, int v, int w)
{
for (int i = w + 1; i < G.vexnum; i++)
{
if (G.arcs[v][i] != MaxInt)
{
return i;
}
}
return -1;
}
bool visited[MVNum];
void DFS(AMGraph G, int v)
{//图G为邻接矩阵类型,从第V个顶点出发深度优先搜索遍历图G
cout << G.vexs[v];
visited[v] = true;
for (int w = FirstAdjVex(G, v); w >= 0; w = NextAdjVex(G, v, w))
{
if (!visited[w])
DFS(G, w);
}
}
void BFS(AMGraph G, int v)
{//按广度优先非递归遍历连通图G
int u, w;
bool visited[MVNum];
SqQueue Q;
cout << G.vexs[v];
visited[v] = true;
InitQueue(Q);
EnQueue(Q, v);
while (!QueueEmpty(Q))
{
DeQueue(Q, u);
for (w = FirstAdjVex(G, u); w >= 0; w = NextAdjVex(G, u, w))
//依次检查u的所有邻接点w,FirstAdjVex(G,U)表示u的第一个邻接点
//NextAdjVex(G,u,w)表示u相对于w的下一个邻接点,w>=0表示存在邻接点
if (!visited[w])
{
cout << G.vexs[w];
visited[w] = true;
EnQueue(Q, w);
}
}
}
int main()
{
int v;
AMGraph G;
CreateUDN(G);
int choice;
puts("请输入选项:");
puts("0:DFS遍历");
puts("1:BFS遍历");
puts("2:结束程序");
puts("");
while(cin>>choice)
{
if(choice == 0)
{
printf("DFS遍历序列为:");
DFS(G, 0);
puts("");
puts("");
}
else if(choice == 1)
{
printf("BFS遍历序列为:");
BFS(G, 0);
puts("");
puts("");
}
else
{
puts("程序结束");
break;
}
puts("0:DFS遍历");
puts("1:BFS遍历");
puts("2:结束程序");
}
return OK;
}