图的遍历(深度优先搜索和广度优先搜索)
一、DFS(深度优先搜索)
#include<iostream>
#include<iomanip>
#include<string.h>
#include<math.h>
#include<malloc/malloc.h>
using namespace std;
#define MaxVertexNum 100 //最大定点数设为100
typedef int EdgeType; //边的权值设为整型
typedef char VertexType[10]; //顶点类型设为字符串
typedef struct
{
VertexType vertex[MaxVertexNum]; //顶点表
EdgeType edges[MaxVertexNum][MaxVertexNum]; //邻接矩阵,即边表
int n,e; //顶点数和边数
}MGraph;
int visited[MaxVertexNum]; //访问标志数组
int LocateVex(MGraph G,VertexType u)
{
int i;
for(i=0;i<G.n;++i)
if(strcmp(u,G.vertex[i])==0)
return i;
return -1;
}
int FirstadjVex(MGraph G,int i)
{ //在图G中,找第i个顶点的第一个邻接点在邻接矩阵中的序号,
//找到返回序号,否则返回-1
int j;
for(j=0;j<G.n;j++)
if(G.edges[i][j]!=0)
return j;
return -1;
}
int NextAdjVex(MGraph G,int k1,int k2)
{ //在图G中,k1是某一个顶点序号,k2是k1的邻接点,
//找顶点k1相对于k2的下一个邻接点在邻接矩阵中的序号,
//找到返回序号,否则返回-1
int i;
for(i=k2+1;i<G.n;i++)
if(G.edges[k1][i]!=0)
return i;
return -1;
}
void DFS(MGraph G,int i)
{ //从图G的第i号顶点出发深度优先遍历图G
int w;
visited[i]=1;
cout<<setw(5)<<G.vertex[i];
for(w=FirstadjVex(G,i);w>=0;w=NextAdjVex(G,i,w))
if(visited[w]==0) //临接点w尚未被访问
{
cout<<"->";
DFS(G,w); //对尚未被访问的w的临接点递归调用DFS(访问w)
}
}
void DFSTraverse(MGraph G)
{ //从第一个顶点起,深度优先遍历图G
int i;
for(i=0;i<G.n;i++) //n代表顶点数,对图G的所有顶点
visited[i]=0; //访问标志数组初始化(未被访问)
for(i=0;i<G.n;i++) //对图G的所有顶点
if(!visited[i]) //顶点i尚未被访问
DFS(G,i); //对尚未被访问的序号为i的顶点调用DFS
}
void CreateMGraphAG(MGraph &G)
{ //建立无向图G的邻接矩阵存储
int i,j,k;
VertexType vi,vj;
cout<< "请输入顶点数和弧数(输入格式为:顶点数,边数):"<<endl;
cin>>G.n>>G.e; //输入顶点数和弧数
cout<< "请输入顶点信息(输入格式为:顶点号<CR>):"<<endl;
for(i=0;i<G.n;i++)
cin>>G.vertex[i]; //输入顶点信息,建立顶点表
for(i=0;i<G.n;i++)
for(j=0;j<G.n;j++)
G.edges[i][j]=0; //初始化邻接矩阵
cout<< "请输入"<<G.e<< "条弧对应的两个顶点的序号(输入格式为:顶点1,顶点2):"<<endl;
for(k=0;k<G.e;k++)
{
cin>>vi>>vj; //输入e条边,建立邻接矩阵
i=LocateVex(G,vi);
j=LocateVex(G,vj);
G.edges[i][j]=1; //对输入的两顶点判断其在矩阵的位置,并赋值1,剩下的定点表明无对应关系,为已经的初始化值0
G.edges[j][i]=1; //区别于有向图,无向图的邻接矩阵为对称矩阵
}
}
void print(MGraph G)
{
int i,j;
for(i=0;i<G.n;i++)
{
for(j=0;j<G.n;j++)
cout<<setw(4)<<G.edges[i][j]; //setw()用来控制间隔
cout<<endl;
}
}
int main()
{
MGraph G;
CreateMGraphAG(G);
cout<<"输出图的邻接矩阵:"<<endl;
print(G);
cout<<"输出图的深度优先遍历序列:"<<endl;
DFSTraverse(G);
return 0;
}
二、BFS(广度优先搜索)
//图的广度优先遍历,图采用邻接表存储,非递归生成图的广度优先遍历序列
#include<iostream>
#include<iomanip>
#include<string>
#include<math.h>
#include<malloc/malloc.h>
using namespace std;
#define MaxVertexNum 100
typedef char VertexType[10];
typedef struct node
{
int adjvex;
struct node * nextedge;
int information;
}EdgeNode;
typedef struct vnode
{
VertexType vertex;
EdgeNode * firstedge;
}VertexNode;
typedef VertexNode AdjList[MaxVertexNum];
typedef struct
{
AdjList adjilist;
int n,e;
}ALGraph;
int visited[MaxVertexNum];
struct QNode
{
int data;
struct QNode * next;
};
typedef struct QNode * Queueptr;
typedef struct LinkQueue
{
Queueptr front,rear;
}LinkQueue;
void InitQueue(LinkQueue &Q)
{ //
Q.front=Q.rear=(Queueptr)malloc(sizeof(QNode));
Q.front->next=NULL;
}
int QueueEmpty(LinkQueue Q)
{
if(Q.front==Q.rear)
return 1;
else return 0;
}
int EnQueue(LinkQueue &Q,int i)
{
Queueptr p;
p=(Queueptr)malloc(sizeof(QNode));
p->data=i;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
return 1;
}
int DeQueue(LinkQueue &Q)
{
int e;
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 e;
}
int LocateVex(ALGraph G,VertexType u)
{
int i;
for(i=0;i<G.n;++i)
if(strcmp(u,G.adjilist[i].vertex)==0)
return i;
return -1;
}
void BFSTraverse(ALGraph G)
{
int i,j,k;
LinkQueue Q;
EdgeNode * p;
for(i=0;i<G.n;i++)
visited[i]=0;
InitQueue(Q);
for(i=0;i<G.n;i++)
if(visited[i]==0)
{
visited[i]=1;
EnQueue(Q,i);
while(!QueueEmpty(Q))
{
j=DeQueue(Q);
cout<<setw(5)<<G.adjilist[j].vertex;
p=G.adjilist[j].firstedge;
while(p)
{
k=p->adjvex;
if(visited[k]==0)
{
visited[k]=1;
EnQueue(Q,k);
}
p=p->nextedge;
}
cout<<"->";
}
}
}
void CreateALGraphAG(ALGraph &G)
{ //建立无向图的邻接表存储
int i,j,k;
VertexType vi,vj;
EdgeNode * s;
cout<<"请输入顶点数和边数(输入格式为:顶点数,边数):"<<endl;
cin>>G.n>>G.e; //读入顶点数和边数
cout<<"请输入顶点信息(输入格式为:顶点号<CR>):"<<endl;
for(i=0;i<G.n;i++) //建立有n个顶点的顶点表
{ //读入顶点信息
cin>>G.adjilist[i].vertex;
G.adjilist[i].firstedge=NULL; //顶点的边表头指针为空
}
cout<<"请输入边的信息(输入格式为:顶点1,顶点2):"<<endl;
for(k=0;k<G.e;k++) //建立边表
{ //输入e条边,建立邻接表
cin>>vi>>vj;
i=LocateVex(G,vi);
j=LocateVex(G,vj);
s=(EdgeNode *) malloc(sizeof(EdgeNode)); //生成新边表结点s
s->adjvex=j; //邻接点序号为j
s->nextedge=G.adjilist[i].firstedge; //将新边表结点s插入到顶点vi的边表头部
G.adjilist[i].firstedge=s;
s=(EdgeNode * )malloc(sizeof(EdgeNode));
s->adjvex=i;
s->nextedge=G.adjilist[j].firstedge;
G.adjilist[j].firstedge=s;
}
}//CreateALGraphAG
int main()
{
ALGraph G;
CreateALGraphAG(G);
cout<<"输出图的广度优先遍历序列:"<<endl;
BFSTraverse(G);
return 0;
}