图的遍历之深度和广度优先搜索
[问题描述]
对给定图,实现图的深度优先遍历和广度优先遍历。
[基本要求]
以邻接表为存储结构,实现连通无向图的深度优先和广度优先遍历。以用户指定的结点为起点,分别输出每种遍历下的结点访问序列。
【测试数据】
由学生依据软件工程的测试技术自己确定。
#include<stdio.h>
#include<iostream>
#include<queue>
using namespace std;
#define MVNum 100//最大顶点数
#define VerTexType char
typedef struct ArcNode//边
{
int adjvex;//该边所指向的顶点位置
struct ArcNode * nextarc;//指向下一条边的指针
}ArcNode;
typedef struct VNode//顶点
{
VerTexType data;
ArcNode *firstarc;//指向第一条依附该顶点的指针
}VNode,AdjList[MVNum];//AdjList表示邻接表类型
typedef struct//邻接表
{
AdjList vertices;
int vexnum,arcnum;//图的当前顶点和边数
}ALGraph;
int LocateVex(ALGraph G,VerTexType x)//确定顶点在图中的位置,即顶点在vertices中的序号
{
for(int i=0;i<G.vexnum;i++)
{
if(x = =G.vertices[i].data)
{
return i;
}
}
return -1;
}
void CreateUDG(ALGraph &G)
{
cout<<"输入顶点数和边数"<<endl;
cin>>G.vexnum>>G.arcnum;//总顶点数,总边数
cout<<"输入顶点信息"<<endl;
for(int i=0;i<G.vexnum;i++)
{
cin>>G.vertices[i].data;//输入顶点值
G.vertices[i].firstarc=NULL;//初始化表头结点
}
cout<<"输入边的两端"<<endl;
for(int k=0;k<G.arcnum;k++)
{
char v1,v2;//边上的两点
int i,j;
cin>>v1>>v2;
i=LocateVex(G,v1);
j=LocateVex(G,v2);
ArcNode *p1=new ArcNode;//新边
p1->adjvex=j;//邻接点序号为j
p1->nextarc=G.vertices[i].firstarc;
G.vertices[i].firstarc=p1;//将新节点插入顶点vi的边表头部
ArcNode *p2=new ArcNode;
p2->adjvex=i;
p2->nextarc=G.vertices[j].firstarc;
G.vertices[j].firstarc=p2;
}
}
bool visited[MVNum];
int FirstAdjVex(ALGraph G,int v)//表示v的第一个邻接点
{
ArcNode* p=G.vertices[v].firstarc;
if(p)
return p->adjvex;
else
return -1;
}
int NextAdjVex(ALGraph G,int v,int w)//v相对于w的下一个邻接点
{
ArcNode* p=G.vertices[v].firstarc;
while(p)
{
if(p->adjvex==w)
break;
else
p=p->nextarc;
}
if(p->adjvex!=w||!p->nextarc)
return -1;
else
return p->nextarc->adjvex;
}
void DFS(ALGraph G,int v)
{
int w;
visited[v]=true;
cout<<G.vertices[v].data;
ArcNode* p=G.vertices[v].firstarc;//p指向边链表的第一个边结点
while(p!=NULL)
{
w=p->adjvex;//w是v的邻接点
if(!visited[w])
DFS(G,w);
p=p->nextarc;//p指向下一个边结点
}
}
void DFS1(ALGraph G)
{
cout<<"深度优先遍历:"<<endl;
for(int i=0;i<G.vexnum;i++)
visited[i]=false;
for(int i=0;i<G.vexnum;i++)
if(!visited[i])
DFS(G,i);
}
void BFS(ALGraph G)
{
queue<int> q;
for(int i=0;i<G.vexnum;i++)
visited[i]=false;
cout<<"广度优先遍历"<<endl;
for(int i=0;i<G.vexnum;i++)
{
if(!visited[i])
{
q.push(i);//入队
visited[i]=true;
while(!q.empty())
{
int v=q.front();
q.pop();//队首元素出队
cout<<G.vertices[v].data;
for(int w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w))
{
if(!visited[w])
{
q.push(w);
visited[w]=true;
}
}
}
}
}
}
int main()
{
ALGraph G;
CreateUDG(G);
DFS1(G);
cout<<endl;
BFS(G);
return 0;
}