题目:图的遍历的实现
完成日期:20##.12.22
一、需求分析
1.本演示程序中,输入的数据类型均为整型数据,不允许输入字符等其他数据类型,且需要按照提示内容进行输入,成对的关系数据必须在所建立的图中已经存在对应的结点。
2.演示程序以用户和计算机的对话方式执行,在计算机终端上显示的提示信息的说明下,按照要求输入数据,运算结果在其后显示。
3.本程序实现分别基于邻接矩阵和邻接表存储结构的有、无向图,有、无向网的建立和遍历。遍历分DFS和BFS两种算法,并分别以递归和非递归形式实现。
4.测试数据:
(1)无向图 结点数 4 弧数 3 结点:1 2 3 4 结点关系:1 2;1 3;2 4
(2)有向图 结点数 6 弧数 6 结点:1 2 3 4 5 6 结点关系:1 2;1 3;2 4;3 5;3 6;2 5
二、概要设计
为实现上述程序功能,图的存储结构分为邻接矩阵和邻接表两种。遍历过程中借助了栈和队列的存储结构。
1.邻接矩阵存储结构的图定义:
ADT mgraph{
数据对象V:V是具有相同特性的的数据元素的集合,成为顶点集。
数据关系 R:
R={VR}
VR={ | v,w ? V且P(v,w),表示从v到w的弧,谓词P(v,w)定义了弧的意义或信息 }
基本操作 P:
locatevex(G, mes);
初始条件:图G存在,mes和G中顶点有相同的特征。
操作结果:若G中存在顶点u,则返回该顶点在图中位置;否则返回其他信息。
createudn( & G);
初始条件:图G 存在。
操作结果:创建无向图。
createdn( & G);
初始条件:图G 存在。
操作结果:创建有向图。
createudg( & G);
初始条件:图G 存在。
操作结果:创建无向网。
createdg(& G);
初始条件:图G 存在。
操作结果:创建有向网。
DFS(G,v);
初始条件:图G已经存在并被赋值,v是图中某个顶点的位置坐标。
操作结果:深度优先搜索遍历图G,访问顶点时使用函数visit.
BFS(G,v);
初始条件:图G已经存在并被赋值,v是图中某个顶点的位置坐标。
操作结果:广度优先搜索遍历图G,访问顶点时使用函数visit.
visit( a);
初始条件:a为图中的某个顶点值。
操作结果:访问顶点a,本程序中作用结果为输出顶点值。
}ADT mgraph
2.邻接表存储结构的图定义:
ADT algraph{
数据对象V:V是具有相同特性的的数据元素的集合,成为顶点集。
数据关系 R:
R={VR}
VR={ | v,w ? V且P(v,w),表示从v到w的弧,谓词P(v,w)定义了弧的意义或信息 }
基本操作 P:
locatevex(G, mes);
初始条件:图G存在,mes和G中顶点有相同的特征。
操作结果:若G中存在顶点u,则返回该顶点在图中位置;否则返回其他信息。
createudn( & G);
初始条件:图G 存在。
操作结果:创建无向图。
createdn( & G);
初始条件:图G 存在。
操作结果:创建有向图。
createudg( & G);
初始条件:图G 存在。
操作结果:创建无向网。
createdg(& G);
初始条件:图G 存在。
操作结果:创建有向网。
DFS(G,v);
初始条件:图G已经存在并被赋值,v是图中某个顶点的位置坐标。
操作结果:深度优先搜索遍历图G,访问顶点时使用函数visit.
BFS(G,v);
初始条件:图G已经存在并被赋值,v是图中某个顶点的位置坐标。
操作结果:广度优先搜索遍历图G,访问顶点时使用函数visit.
visit( a);
初始条件:a为图中的某个顶点值。
操作结果:访问顶点a,本程序中作用结果为输出顶点值。
}ADT algraph
3.主程序流程:
定义并创建图
status creatgraph(mgraph & G)
{
cout<<"请选择构造的图的类型:( 1:有向图,2:有向网,3:无向图,4:无向网)"
<
int kind;
scanf("%d",& kind);
switch (kind)//通过选择确定创建哪一种图;
{
case 1: return createdg(G);
case 2: return createdn(G);
case 3:return createudg(G);
case 4: return createudn(G);
default: return error;
}
}
然后采用DFS或BFS进行遍历(访问结果为输出顶点值)。
4.函数的调用关系图:
其中,当DFS使用递归算法时相关的栈操作不使用,当BFS使用递归算法时相关的队列操作仍有部分使用。
四、调试分析
1.采用邻接表结构创建图时,由于没有正确进行弧元素的跟进插入,导致图创建不成功。
2.没有采用多文件结构,导致在快要完成时发现函数定义的位置不尽合理,后续添加功能时难度增大。
3.本程序主要为实现遍历算法思想,对实用性考虑偏少,但考虑到了多种数据类型情况下的分别实现,函数拆分较详细,算法可靠性强。
4.算法的时空分析
1)由于对顶点元素的存储均采用了线性结构,所以在创建图和遍历时多依赖于该线性存储的大小。当结点个数为n,弧条数为e时, createdg createdn createudg createudn的算法时间复杂度都为O(n²+e*n),其中对邻接矩阵的初始化耗费了O(n²)的时间。
2)当用二维数组表示邻接矩阵作为图的存储结构时,查找每个顶点的邻接点所需时间为O(n²),而以邻接表为存储结构时为O(e)。以邻接表为存储结构时,深度优先搜索遍历图(DFS)的时间复杂度为O(n+e)。
3)广度优先搜索遍历图(BFS)的时间复杂度和深度优先搜索遍历(DFS)相同。
5.对链表的操作需要很重要的一个量来定位链表和定位操作的位置,指针的作用不可替代。多种数据结构的联合使用在程序中非常重要,多种存储结构的程序实现原理上相同,但具体的操作技巧有很大差别。
五、用户使用说明
1.本程序运行环境建议为window xp.
2.打开程序工程,并运行其中可执行文件,终端对话框会出现文字提示,请严格按照文字提示进行输入操作。
3.数据之间的分隔可用空格或回车键执行。
4.如下图是某无向图的创建并进行DFS的结果:
六、测试结果
DFS:
七、附录
邻接矩阵结构创建图:
#include
#include
#include
typedef int vertextype;
typedef int infotype;
typedef int status;
typedef int selemtype;
#define error 0
#define ok 1
#define INFINTY INT_MAX //最大值∞
#define MAX_VERTEX_NUM 20 //最大定点个数
#define FALSE 0
#define TRUE 1
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define overflow -2
using namespace std;
//弧定义
typedef struct arccell
{int adj;
// infotype *info;
}arccell,adjmatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
//图定义
typedef struct
{
vertextype vexs[MAX_VERTEX_NUM];//顶点
adjmatrix arcs;// 弧矩阵
int vexnum,arcnum;
}mgraph;
int locatevex(mgraph G,vertextype mes)
{
for(int i=0;i
if(mes==G.vexs[i])
return i;
return 0;
}//定位函数
//创建无向网
status createudn(mgraph & G)
{
cout<<"请输入无向网的顶点数,弧数:"<
scanf("%d%d",&G.vexnum,&G.arcnum);
cout<<"请输入各顶点的值:"<
for(int i=0;i
for(int i=0;i
for(int j=0;j
G.arcs[i][j].adj=0;
cout<<"请输入成对的关系顶点数值以及其权值:(形如:11 22 1)"<
for(int k=0;k
{vertextype v1,v2;
int w;
scanf("%d%d%d", &v1,&v2,&w);
int i=locatevex(G,v1);int j=locatevex(G,v2);
G.arcs[i][j].adj=w;
G.arcs[j][i]=G.arcs[i][j];
}
return ok;
}
//创建有向网
status createdn(mgraph & G)
{
cout<<"请输入有向网的顶点数,弧数:"<
scanf("%d%d",&G.vexnum,&G.arcnum);
cout<<"请输入各顶点的值:"<
for(int i=0;i
for(int i=0;i
for(int j=0;j
G.arcs[i][j].adj=0;
cout<<"请输入成对的关系顶点数值以及其权值:(形如:11 22 1)"<
for(int k=0;k
{
vertextype v1,v2;
int w;
scanf("%d%d%d", &v1,&v2,&w);
int i=locatevex(G,v1);int j=locatevex(G,v2);
G.arcs[i][j].adj=w;
}
return ok;
}
//创建无向图
status createudg(mgraph & G)
{
cout<<"请输入无向图的顶点数,弧数:"<
scanf("%d%d",&G.vexnum,&G.arcnum);
cout<<"请输入各顶点的值:"<
for(int i=0;i
for(int i=0;i
for(int j=0;j
G.arcs[i][j].adj=0;
cout<<"请输入成对的关系顶点数值:(形如:11 22 )"<
for(int k=0;k
{
vertextype v1,v2;
scanf("%d%d", &v1,&v2);
int i=locatevex(G,v1);int j=locatevex(G,v2);
G.arcs[i][j].adj=1;
G.arcs[j][i]=G.arcs[i][j];
}
return ok;
}
//创建有向图
status createdg(mgraph & G)
{
cout<<"请输入有向图的顶点数,弧数:"<
scanf("%d%d",&G.vexnum,&G.arcnum);
cout<<"请输入各顶点的值:"<
for(int i=0;i
for(int i=0;i
for(int j=0;j
G.arcs[i][j].adj=0;
cout<<"请输入成对的关系顶点数值:(形如:11 22 )"<
for(int k=0;k
{
vertextype v1,v2;
scanf("%d%d", &v1,&v2);
int i=locatevex(G,v1);int j=locatevex(G,v2);
G.arcs[i][j].adj=1;
}
return ok;
}
邻接矩阵的DFS非递归算法:
void visit(vertextype a)
{printf("--%d-",a);}
void DFS(mgraph G,int v)
{
int visitp[MAX_VERTEX_NUM];
sqstack S;
if(initstack(S)==1);
for(int i=0;i
visitp[i]=FALSE;
//首先访问第一个顶点
visit(G.vexs[v]);
visitp[v]=TRUE;
push(S, G.vexs[v]);
while (S.top!=S.base)//若栈不为空,则继续从栈顶元素进行遍历
{
int k=0,m=0,num=0,j=0 ,temp=0;
gettop(S,k);
m=locatevex(G,k);
//得到栈顶元素,并在图中定位
for(j=0;j
if((G.arcs[m][j].adj)!=0 && visitp[j]==FALSE)
num+=1;
if(num==0) //如果与栈顶元素相关联的顶点都被访问过,则删除栈顶元素
pop(S,temp);
//如果与栈顶元素相关联的顶点还有未被访问的,
//则将与其相关联的顶点全部访问
else
for(int w=0;w
if(G.arcs[m][w].adj !=0 && visitp[w]==FALSE)
{
visit(G.vexs[w]);//执行visit操作
visitp[w]=TRUE;//访问标志置真
push(S,G.vexs[w]);//刚访问的顶点入栈
break;
}
}
destroystack(S);
}
邻接矩阵的DFS递归算法:
int visitp[MAX_VERTEX_NUM];//全局变量,
//注意在main函数中都赋初值FALSE
void visit(vertextype a)
{printf("--%d-",a);}
void DFS(mgraph G,int v)
{
visit(G.vexs[v]);
visitp[v]=TRUE;
for(int j=0;j
if((G.arcs[v][j].adj)!=0 && visitp[j]==FALSE)
DFS(G,j);
}
邻接矩阵存储结构的BFS非递归算法:
void visit(vertextype a)
{printf("--%d-",a);}
void BFS(mgraph G,int v)
{
int visitp[MAX_VERTEX_NUM];
linkqueue Q;
if(initqueue(Q)==1)
for(int i=0;i
visitp[i]=FALSE;
else exit(1);
//首先访问第一个顶点
visit(G.vexs[v]);
visitp[v]=TRUE;
enqueue(Q,G.vexs[v]);
while (Q.front!=Q.rear)
{
int k=0,m=0,num=0,temp=0,j=0;
gethead(Q,k);
m=locatevex(G,k);//得到队首元素并定位
for(j=0;j
if((G.arcs[m][j].adj)!=0 && visitp[j]==FALSE)
num+=1;
if(num==0)
dequeue(Q,temp);//如果此顶点的后继均访问过,则从队列中删除
else
{
for(int w=0;w
if(G.arcs[m][w].adj !=0 && visitp[w]==FALSE)
{visit(G.vexs[w]);//执行visit操作
visitp[w]=TRUE;//访问标志置真
enqueue(Q,G.vexs[w]);}
}
}
destroyqueue(Q);
}
邻接矩阵存储结构的BFS递归算法:
void BFS(mgraph G,int v)
{
linkqueue Q;
initqueue(Q);
if(visitp[v]==FALSE)
{
visit(G.vexs[v]);
visitp[v]=TRUE;
}
int j;
int e;
int address;
for(j=0;j
if((G.arcs[v][j].adj)!=0 && visitp[j]==FALSE)
{
visit(G.vexs[j]);
visitp[j]=TRUE;
enqueue(Q,G.vexs[j]);
}
while (Q.front!=Q.rear)
{
dequeue(Q,e);
address=locatevex(G,e);
BFS(G,address);
}
destroyqueue(Q);
}
int main()
{
mgraph G;
creatgraph(G);
int i;
for(i=0;i
visitp[i]=FALSE;
BFS(G,0);
return 0;
}
邻接表存储结构的图的创建:
#include
#include
#include
typedef int vertextype;
typedef int infotype;
typedef int status;
typedef int selemtype;
#define FALSE 0
#define TRUE 1
#define error 0
#define ok 1
#define MAX_VERTEX_NUM 20 //最大顶点个数
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define overflow -2
using namespace std;
typedef struct arcnode{
int adjvex; //弧指向的顶点的位置
int adj;//权值
struct arcnode *nextrarc; //指向下一条弧的指针
infotype *info;
}arcnode;
//顶点结点定义
typedef struct vnode{
vertextype data; //顶点数据
arcnode *firsttarc;//指向第一条依附该顶点的弧的指针
}vnode,adjlist[MAX_VERTEX_NUM];
//图定义
typedef struct{
adjlist vertices;//顶点数组
int vexnum,arcnum;//顶点数目,弧数目
int kind; //图的种类标志,以数字代表
}algraph;
int locatevex(algraph G,vertextype mes){
for(int i=0;i
if(mes==G.vertices[i].data)
return i;
return -1;
}
//创建无向网
status createudn(algraph &G){
cout<<"请输入无向网的顶点数,弧数:"<
scanf("%d%d",&G.vexnum,&G.arcnum);//输入顶点数和弧数
cout<<"请输入各顶点的值:"<
for(int i=0;i
scanf("%d",&G.vertices[i].data); //输入并构造顶点
for(int i=0;i
G.vertices[i].firsttarc=NULL;//初始化指针firsttarc
cout<<"请输入成对的关系顶点数值以及其权值:(形如:11 22 1)"<
for(int k=0;k
{ vertextype v1,v2;
int w;//权值
scanf("%d%d%d", &v1,&v2,&w); getchar();
int i=locatevex(G,v1);
int j=locatevex(G,v2);//定位
arcnode * a;
a=(arcnode *)malloc(sizeof (arcnode));//为加入的弧结点申请空间
if (a==NULL)
exit(1);
( * a).adjvex=j;(* a).adj=w;(* a).nextrarc=NULL;(* a).info=NULL;
if(G.vertices[i].firsttarc==NULL)
G.vertices[i].firsttarc=a;//当此弧是顶点i的第一条弧时
else//当此弧不是顶点i的第一条弧时
{a->nextrarc=G.vertices[i].firsttarc->nextrarc;
G.vertices[i].firsttarc=a;}
//处理另一条对称的顶点j
if(G.vertices[j].firsttarc==NULL)
G.vertices[j].firsttarc=a;//当此弧是顶点j的第一条弧时
else//当此弧不是顶点j的第一条弧时
{a->nextrarc=G.vertices[j].firsttarc->nextrarc;
G.vertices[j].firsttarc=a;}
}
return ok;
}
//有向网
status createdn(algraph &G)
{
cout<<"请输入有向网的顶点数,弧数:"<
scanf("%d%d",&G.vexnum,&G.arcnum);
cout<<"请输入各顶点的值:"<
for(int i=0;i
scanf("%d",&G.vertices[i].data); //构造顶点
for(int i=0;i
G.vertices[i].firsttarc=NULL;//初始化指针firsttarc
cout<<"请输入成对的关系顶点数值以及其权值:(形如:11 22 1)"<
for(int k=0;k
{ vertextype v1,v2;
int w;
scanf("%d%d%d", &v1,&v2,&w);getchar();
int i=locatevex(G,v1);
int j=locatevex(G,v2);
arcnode * a;
a=(arcnode *)malloc(sizeof (arcnode));
if (a==NULL)
exit(1);
( * a).adjvex=j;(* a).adj=w;(* a).nextrarc=NULL; (* a).info=NULL;
if(G.vertices[i].firsttarc==NULL)
G.vertices[i].firsttarc=a;//当此弧是顶点i的第一条弧时
else//当此弧不是顶点i的第一条弧时连接到第一条弧位置,将原来的弧接到后面
{a->nextrarc=G.vertices[i].firsttarc->nextrarc;
G.vertices[i].firsttarc=a;}
}
return ok;
}
//无向图
status createudg(algraph &G)
{
cout<<"请输入无向图的顶点数,弧数:"<
scanf("%d %d",&G.vexnum,&G.arcnum);getchar();
cout<<"请输入各顶点的值:"<
for(int i=0;i
{scanf("%d",&G.vertices[i].data);}//顶点赋值
getchar();
for(int i=0;i
G.vertices[i].firsttarc=NULL;//初始化指针firsttarc
cout<<"请输入成对的关系顶点数值:(形如:11 22 )"<
for(int k=0;k
{ vertextype v1,v2;
scanf("%d%d", &v1,&v2);getchar();
int i=locatevex(G,v1);
int j=locatevex(G,v2);
arcnode * a;
a=(arcnode *)malloc(sizeof (arcnode));//为加入的弧结点申请空间
if (a==NULL)
exit(1);
( * a).adjvex=j;(* a).adj=1; (* a).nextrarc=NULL; (* a).info=NULL;
if(G.vertices[i].firsttarc==NULL)//当此弧是顶点i的第一条弧时{
G.vertices[i].firsttarc=a;//cout<<"attach to firsttarc"<
else//当此弧不是顶点i的第一条弧时
{a->nextrarc=G.vertices[i].firsttarc;
G.vertices[i].firsttarc=a; //cout<<"attach successfully!"<
}
//处理对称的另一个顶点
if(G.vertices[j].firsttarc==NULL)//当此弧是顶点j的第一条弧时{
G.vertices[j].firsttarc=a;//cout<<"attach to firsttarc"<
else//当此弧不是顶点j的第一条弧时
{a->nextrarc=G.vertices[j].firsttarc;
G.vertices[j].firsttarc=a; //cout<<"attach successfully!"<
}
}return ok;
}
status createdg(algraph &G)
{
cout<<"请输入无向图的顶点数,弧数:"<
scanf("%d %d",&G.vexnum,&G.arcnum);getchar();
cout<<"请输入各顶点的值:"<
for(int i=0;i
{scanf("%d",&G.vertices[i].data);}//顶点赋值
getchar();
for(int i=0;i
G.vertices[i].firsttarc=NULL;//初始化指针firsttarc
cout<<"请输入成对的关系顶点数值:(形如:11 22 )"<
for(int k=0;k
{ vertextype v1,v2;
scanf("%d%d", &v1,&v2);getchar();
int i=locatevex(G,v1);
int j=locatevex(G,v2);
arcnode * a;
a=(arcnode *)malloc(sizeof (arcnode));//为加入的弧结点申请空间
if (a==NULL)
exit(1);
( * a).adjvex=j;(* a).adj=1; (* a).nextrarc=NULL; (* a).info=NULL;
if(G.vertices[i].firsttarc==NULL)//当此弧是顶点i的第一条弧时{
G.vertices[i].firsttarc=a;//cout<<"attach to firsttarc"<
else//当此弧不是顶点i的第一条弧时
{a->nextrarc=G.vertices[i].firsttarc;
G.vertices[i].firsttarc=a; //cout<<"attach successfully!"<
}
}return ok;
}
邻接表存储结构的额DFS非递归算法:
//visit函数
void visit(vertextype a)
{printf("--%d-",a);}
//DFS
void DFS(algraph G,int v){
int visitp[MAX_VERTEX_NUM];//访问标记数组,
sqstack S;
initstack(S);//建立存储访问过结点的栈
for(int i=0;i
visitp[i]=FALSE;//将各顶点访问标记均赋值为FALSE
visit(G.vertices[v].data);
visitp[v]=TRUE;
push(S,G.vertices[v].data);//访问并入栈第一个顶点
while(S.base!=S.top)//当栈不为空时进行遍历
{
arcnode * p;
int num=0,temp=0,k=0,m=0;
gettop(S,k);//得到栈顶元素
m=locatevex(G,k);//定位栈顶元素在图中的坐标
for(p=G.vertices[m].firsttarc;p!=NULL;p=p->nextrarc)
{if(visitp[(* p).adjvex]==FALSE) num+=1;}
//cout<<"there are"<
if(num==0)//如果此顶点的后继顶点都被访问过,则从栈中删除此顶点
{ pop(S,temp);cout<<"no point left"<
else
{for(p=G.vertices[m].firsttarc;p!=NULL;p=p->nextrarc)
if(visitp[(* p).adjvex]==FALSE)
{ visit( G.vertices[(* p).adjvex].data);
visitp[(* p).adjvex]=TRUE;
push(S,G.vertices[(* p).adjvex].data);
break;//因为是深度优先,所以遇到可访问顶点并访问后跳出for循环
}
}
}destroystack(S);//销毁辅助栈
}
邻接表存储结构的DFS递归算法:
int visitp[MAX_VERTEX_NUM];//全局变量,
//注意在main函数中都赋初值FALSE
void visit(vertextype a)
{printf("--%d-",a);}
void DFS(algraph G,int v)
{
visit(G.vertices[v].data);
visitp[v]=TRUE;
for( arcnode * p=G.vertices[v].firsttarc;p!=NULL;p=p->nextrarc)
if(visitp[p->adjvex]==FALSE)DFS(G,p->adjvex);
}
int main()
{algraph G;
createudg(G);
for(int i=0;i
visitp[i]=FALSE;
DFS(G,0);
return 0;
}
邻接表存储结构的BFS非递归算法:
void visit(vertextype a)
{printf("--%d-",a);}
void BFS(algraph G,int v)
{
int visitp[MAX_VERTEX_NUM];
linkqueue Q;
if(initqueue(Q)==1)
for(int i=0;i
visitp[i]=FALSE;
else exit(1);
//首先访问第一个顶点
visit(G.vertices[v].data);
visitp[v]=TRUE;
enqueue(Q,G.vertices[v].data);
while (Q.front!=Q.rear)
{
int k=0,m=0,num=0,temp=0;
gethead(Q,k);
m=locatevex(G,k);//得到队首元素并定位
for(arcnode * j=G.vertices[m].firsttarc;j!=NULL;j=j->nextrarc)
if(visitp[(* j).adjvex]==FALSE)
num+=1;
if(num==0)
dequeue(Q,temp);//如果此顶点的后继均访问过,则从队列中删除
else
{
for(arcnode * p=G.vertices[m].firsttarc;p!=NULL;p=p->nextrarc)
if(visitp[(* p).adjvex]==FALSE)
{visit( G.vertices[(* p).adjvex].data);//执行visit操作
visitp[(* p).adjvex]=TRUE;//访问标志置真
enqueue(Q,G.vertices[(* p).adjvex].data);
}
}
}
destroyqueue(Q);
}
int main()
{
algraph G;
createudg(G);
BFS(G,0);
return 0;
}
//邻接表存储结构的BFS递归算法
void visit(vertextype a)
{printf("--%d-",a);}
int visitp[MAX_VERTEX_NUM];
void BFS(algraph G,int v)
{ linkqueue Q;
initqueue(Q);
if(visitp[v]==FALSE)
{
visit(G.vertices[v].data);
visitp[v]=TRUE;
}//访问标记,
int e;
int address;
arcnode * p;
for(p=G.vertices[v].firsttarc;p!=NULL;p=p->nextrarc)
if(visitp[(* p).adjvex]==FALSE)
{
visit( G.vertices[(* p).adjvex].data);
visitp[(* p).adjvex]=TRUE;
enqueue(Q,G.vertices[(* p).adjvex].data);
}//访问该与结点有关系的全部结点
while (Q.front!=Q.rear)
{
dequeue(Q,e);
address=locatevex(G,e);
BFS(G,address);//递归调用BFS
}
destroyqueue(Q);
}
int main()
{
algraph G;
createudg(G);
int i;
for(i=0;i
visitp[i]=FALSE;
BFS(G,0);
return 0;
}
辅助队列的实现:
#include
#include
#include
#include
#include
typedef int vertextype;
typedef int infotype;
typedef int status;
typedef int qelemtype;
#define error 0
#define ok 1
#define INFINTY INT_MAX //最大值∞
#define MAX_VERTEX_NUM 20 //最大定点个数
#define overflow -2
#define FALSE 0
#define TRUE 1
using namespace std;
typedef struct qnode{
qelemtype data;
struct qnode *next;
}qnode,* queueptr;
typedef struct {
queueptr front;//队头指针
queueptr rear;//队尾指针
}linkqueue;
status initqueue(linkqueue &Q);
status gethead(linkqueue Q,qelemtype &e);
status enqueue(linkqueue &Q,qelemtype e);
status dequeue(linkqueue &Q,qelemtype &e);
status destroyqueue(linkqueue &Q);
status initqueue(linkqueue &Q)
{
Q.front=Q.rear=(queueptr)malloc(sizeof(qnode));
if(!Q.front)exit(overflow);
Q.front->next=NULL;
return ok;
}
status gethead(linkqueue Q,qelemtype &e)
{
if(Q.front==Q.rear)
return error;
e=Q.front->next->data;
return ok;
}
status enqueue(linkqueue &Q,qelemtype e)
{
queueptr p;
p=(queueptr)malloc(sizeof (qnode));
if(!p) exit(overflow);
p->data=e;p->next=NULL;
Q.rear->next=p;
Q.rear=p;
return ok;
}
status dequeue(linkqueue & Q,qelemtype &e)
{
if(Q.front==Q.rear)return error;
queueptr p;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p)Q.rear=Q.front;
free(p);
return ok;
}
status destroyqueue(linkqueue &Q)
{
while(Q.front)
{ Q.rear=Q.front->next;
free(Q.front);
Q.front=Q.rear;
}
return ok;
}
辅助栈的实现:
#include
#include
#include
typedef int vertextype;
typedef int infotype;
typedef int status;
typedef int selemtype;
#define FALSE 0
#define TRUE 1
#define error 0
#define ok 1
#define MAX_VERTEX_NUM 20 //最大定点个数
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define overflow -2
using namespace std;
typedef struct {
selemtype *base;
selemtype *top;
int stacksize;
}sqstack;//栈结构
status initstack(sqstack &S);//构造一个空栈S;
status gettop(sqstack S,selemtype &e);//得到栈顶元素;
status push(sqstack &S,selemtype e);//将元素压入栈;
status pop(sqstack &S,selemtype &e);//删除栈顶元素;
status destroystack(sqstack &S);//销毁栈
status initstack(sqstack &S){
S.base= (selemtype *)malloc(STACK_INIT_SIZE*sizeof (selemtype));
if(!S.base) exit(overflow);
S.top =S.base;
S.stacksize = STACK_INIT_SIZE;
return ok;
}//initstack
status gettop(sqstack S,selemtype &e){
if(S.top == S.base) return error;
e= *(S.top-1);
//cout<<"得到栈顶元素:"<
return ok;
}//gettop
status push(sqstack &S,selemtype e){
if(S.top -S.base>=S.stacksize)
{S.base =(selemtype *)realloc(S.base,(S.stacksize+ STACKINCREMENT)*sizeof(selemtype));
if(!S.base)exit(overflow);
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;
}
*S.top ++ =e;
//cout<<"Push "<
return ok;
}//push
status pop(sqstack &S,selemtype &e){
if(S.top ==S.base)return error;
e=*--S.top;
// cout<<"Pop"<
return ok;
}//pop
status destroystack(sqstack &S){
S.top=S.base;free(S.base);return ok;
}