连通无向图的遍历
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/*问题描述:
编写程序,实现连通无向图的遍历。
基本要求:
以邻接多重表为存储结构,实现连通无向图的深度优先和广度优先遍历。以用户指定的顶点为起点,分别输出每种遍历下的顶点访问序列和相应生成树的边集。
实现提示:
设图的顶点不超过20个,每个顶点用一个编号表示(如果一个图有n个顶点,则它们的编号分别为1,2,…,n)。通过输入图的全部边输入一个图,每条边为一对整数,可以对边的输入顺序作某种限制。注意,生成树的边是有向边,端点顺序不能颠倒。
*/
#include
using namespace std;
//--------------------------------------------------------无向图的邻接多重表存储结构的定义
const int NUM=20;
const int Data_Num=2;//每个顶点所表示的数据
typedef char VertexType[Data_Num];
typedef struct EBox
{
int mark;//访问标记,1代表已访问,0代表未访问
int ivex,jvex;//该边依附的两个顶点的位置
struct EBox *ilink,*jlink;//分别指向依附这两个顶点的下一条边
//InfoType *info;//该边信息指针
}EBox;
typedef struct VexBox
{
VertexType data;
EBox *firstedge;//指向第一条依附该顶点的边
}VexBox;
typedef struct
{
VexBox adjmulist[NUM];
int vexnum,edgenum;//无向图的当前顶点数和边数
}AMLGraph;
//---------------------------------------------------队列的定义
typedef int QElemType;
typedef struct QNode
{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct
{
QueuePtr front,rear;
}LinkQueue;
//寻找输入的数据在图中的位置,若不存在则返回-1
int LocateVex(AMLGraph G,VertexType u)
{
int i;
for(i=0;i
return i;
return -1;
}
//采用邻接多重表存储表示,构造无向图G
int CreateGraph(AMLGraph &G)
{
cout<<"请输入图的顶点数、弧数:";
cin>>G.vexnum;//输入图当前的顶点数
cin>>G.edgenum;//输入图当前的边数
cout<<"请输入每个顶点所对应的值:"<
cin>>G.adjmulist[i].data;//输入顶点值
G.adjmulist[i].firstedge=NULL;//初始化指针
}
VertexType v1,v2;
EBox *p;
int j;//每条弧所关联的两个结点
for(int k=0;k
cout<<"请输入第"<
i=LocateVex(G,v1);j=LocateVex(G,v2);//确定v1和v2在图G中的位置
p=(EBox *)malloc(sizeof(EBox));
//对弧结点进行赋值
(*p).mark=0;
(*p).ivex=i;
(*p).jvex=j;
(*p).ilink=G.adjmulist[i].firstedge;
(*p).jlink=G.adjmulist[j].firstedge;
G.adjmulist[i].firstedge=G.adjmulist[j].firstedge=p;
}
return 1;
}
//返回V的值
VertexType* GetVex(AMLGraph G,int v)
{
if(v>G.vexnum||v<0)
exit(0);
return &G.adjmulist[v].data;
}
//返回V的第一个邻接点的序号,
若没有则返回-1
int FirstAdjVex(AMLGraph G,VertexType v)
{
int i;
i=LocateVex(G,v);
if(i<0)
return -1;
if(G.adjmulist[i].firstedge)//V有邻接结点
if(G.adjmulist[i].firstedge->ivex==i)
return G.adjmulist[i].firstedge->jvex;
else
return G.adjmulist[i].firstedge->ivex;
else
return -1;
}
//返回V的(相对于W)的下一个邻接结点的序号,若W是V的最后一个邻接结点,则返回-1
int NextAdjVex(AMLGraph G,VertexType v,VertexType w)
{
int i,j;
EBox *p;
i=LocateVex(G,v);
j=LocateVex(G,w);
if(i<0||j<0)
return -1;
p=G.adjmulist[i].firstedge;
while(p)
if(p->ivex==i&&p->jvex!=j)
p=p->ilink;
else if(p->jvex==i&&p->ivex!=j)
p=p->jlink;
else
break;
if(p&&p->ivex==i&&p->jvex==j)
{
p=p->ilink;
if(p&&p->ivex==i)
return p->jvex;
else if(p&&p->jvex==i)
return p->jvex;
}
if(p&&p->ivex==j&&p->jvex==i)
{
p=p->jlink;
if(p&&p->ivex==i)
return p->jvex;
else if(p&&p->jvex==i)
return p->jvex;
}
return -1;
}
//------------------------------------队列的操作
int visite[NUM];//访问标志数组
int (*VisitFunc)(VertexType v);
void DFS(AMLGraph G,int v)
{
int j;
EBox *p;
VisitFunc(G.adjmulist[v].data);
visite[v]=1;//该顶点已经被访问
p=G.adjmulist[v].firstedge;
while(p)
{
j=p->ivex==v?p->jvex:p->ivex;
if(!visite[j])
DFS(G,j);
p=p->ivex==v?p->ilink:p->jlink;
}
}
//深度优先遍历图
void DFSTraverse(AMLGraph G,int(*Visit)(VertexType))
{
int v,start;
VisitFunc=Visit;
for(v=0;v
cout<<"请输入你要开始进行查找的位置:";
cin>>start;
cout<<"按广深度优先搜索的结果是:"<
if(v>=G.vexnum)
{
for(v=0;v
if(!visite[v])
DFS(G,v);
}//内层for
}//if
else
{
if(!visite[v])
DFS(G,v);
}//else
}//外层for
cout<<"\b\b\b ";
cout<
//队列的初始化
int InitQueue(LinkQueue *Q)
{
(*Q).front=(*Q).rear=(QueuePtr)malloc(sizeof(QNode));
if(!(*Q).front)
exit(0);
(*Q).front->next=NULL;
return 1;
}
//判断队列是否为空,为空则返回1,否则返回0
int QueueEmpty(LinkQueue Q)
{
if(Q.front==Q.rear)
return 1;
else
return 0;
}
//向队列中插入元素
int EnQueue(LinkQueue *Q,QElemType e)
{
QueuePtr p=(QueuePtr)malloc(sizeof(QNode));
if(!p)
exit(0);
p->data=e;
p->next=NULL;
(*Q).rear->next=p;
(*Q).rear=p;
return 1;
}
//若队列不为空,则删除对头元素,并返回1;否则返回 0
int DeQueue(LinkQueue *Q,QElemType *e)
{
QueuePtr p;
if((*Q).front==(*Q).rear)
return 0;
p=(*Q).front->next;
*e=p->data;
(*Q).front->next=p->next;
if((*Q).rear==p)
(*Q).rear=(*Q).front;
free(p);
return 1;
}
//广度优先非递归遍历图G
void BFSTraverse(AMLGraph G,int(*Visit)(VertexType))
{
int
u,v,w,start=0;
VertexType w1,u1;
LinkQueue Q;
for(v=0;v
InitQueue(&Q);
cout<<"请输入你要开始进行查找的位置:";
cin>>start;
cout<<"按广度优先搜索的结果是:"<
if(!visite[v])
{
visite[v]=1;
Visit(G.adjmulist[v].data);
EnQueue(&Q,v);//v入队列
while(!QueueEmpty(Q))
{
DeQueue(&Q,&u);
strcpy(u1,*GetVex(G,u));
for(w=FirstAdjVex(G,u1);w>=0;w=NextAdjVex(G,u1,strcpy(w1,*GetVex(G,w))))
if(!visite[w])
{
visite[w]=1;
Visit(G.adjmulist[w].data);
EnQueue(&Q,w);
}
}
}
}//for
InitQueue(&Q);
for(v=0;v
if(!visite[v])
{
visite[v]=1;
Visit(G.adjmulist[v].data);
EnQueue(&Q,v);//v入队列
while(!QueueEmpty(Q))
{
DeQueue(&Q,&u);
strcpy(u1,*GetVex(G,u));
for(w=FirstAdjVex(G,u1);w>=0;w=NextAdjVex(G,u1,strcpy(w1,*GetVex(G,w))))
if(!visite[w])
{
visite[w]=1;
Visit(G.adjmulist[w].data);
EnQueue(&Q,w);
}
}
}
}//for
cout<<"\b\b\b ";
cout<
//把边的访问标记设置为0,即未被访问
void MarkUnVisited(AMLGraph G)
{
int i;
EBox *p;
for(i=0;i
p=G.adjmulist[i].firstedge;
while(p)
{
p->mark=0;
if(p->ivex==i)
p=p->ilink;
else
p=p->jlink;
}
}
}
//显示构造的无向图(包括定点数、顶点、边数、边)
void Display(AMLGraph G)
{
int i;
EBox *p;
MarkUnVisited(G);
cout<
p=G.adjmulist[i].firstedge;
while(p)
if(p->ivex==i)
{
if(!p->mark)
{
cout<
p->mark=1;//已经被访问过了
}
p=p->ilink;
}
else
{
if(!p->mark)
{
cout<
}
p=p->jlink;
}
cout<
}
int Visit(VertexType v)
{
cout<
return 1;
}
int main()
{
int flag=1,control,YES=0;
AMLGraph g;
while(flag)
{
cout<<"-----------------------------------------------------"<
switch(control)
{
case 1:
YES=CreateGraph(g);
break;
case 2:
if(YES)
Display(g);
else
{
cout<<"请先创建无向图,再选择此项"<
}
brea
k;
case 3:
if(YES)
{
DFSTraverse(g,Visit);
}
else
{
cout<<"请先创建无向图,再选择此项"<
}
break;
case 4:
if(YES)
{
BFSTraverse(g,Visit);
}
else
{
cout<<"请先创建无向图,再选择此项"<
}
break;
case 0:
flag=0;
break;
}//switch
}//while
return 0;
}