三、已知一个连通图如下图所示,分别给出一个按深度优先遍历和广度优先遍历的顶点序列(假设从顶点v1出发)。并编程分别实现该图的邻接矩阵表示和邻接表表示,要求编写相关基本操作,并在主函数中求出深度优先序列和广度优先序列。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rYy7xOw2-1612100174218)(图3.assets/clip_image002.jpg)]
无向图邻接矩阵DFS/BFS
//无向图邻接矩阵表示实现深度优先遍历和广度优先遍历
#include <iostream>
#define maxValue max
#define E 50
#define V 20
using namespace std;
typedef struct{
char vexlist[V]; //顶点集
int edge[E][E]; //矩阵表
int n,e; //矩阵的边数,顶点数目
}MTGraph;
void CreateMGraph(MTGraph *G){
int i,j;
//输入图的边数和点数
cout<<"please cin the mount of point and edge:";
cin>>G->n;
cin>>G->e;
//输入顶点信息
cout<<"please cin the information of each point:";
for(i=0;i<G->n;i++){
cin>>G->vexlist[i];
}
//邻接矩阵初始化
for(i=0;i<G->n;i++){
for(j=0;j<G->n;j++){
G->edge[i][j]=0;
}
}
//输入图中边的节点(i,j),此处权值为1
cout<<"please cin position_info of each point:";
for(int k=0;k<G->e;k++) {
cin>>i;
cin>>j;
G->edge[i-1][j-1] =1;
G->edge[j-1][i-1] =1;
}
}
void print(MTGraph *G){
cout<<"all information of the graph:\n ";
int i,j;
for(i=0;i<G->n;i++){
cout<<G->vexlist[i]<<" ";
}
cout<<endl;
cout<<"the data of the matrix:\n";
for(i=0;i<G->n;i++){
for(j=0;j<G->n;j++){
cout<<G->edge[i][j]<<" ";
}
cout<<endl;
}
}
//深度优先遍历
typedef enum{FALSE ,TRUE} Boolean;
Boolean visited[V]; //访问标记数组是全局变量
//顶点的先深编号
void DFS(MTGraph *G, int i) //以vi为出发点对邻接矩阵表示的图G进行深度优先搜索
{
int j;
cout<<G->vexlist[i]<<" "; //访问定点vi
visited[i]=TRUE; //标记vi已访问
for( j=0; j<G->n; j++) //依次搜索vi的邻接点
if((G->edge[i][j] == 1) && !visited[j] ) //若vj尚未访问
DFS( G, j );
}//DFS
void DFSTraverse (MTGraph *G)
//先深搜索一邻接表表示的图G;而以邻接矩阵表示G时,算法完全相同.
{
cout<<"深度优先搜索结果:\n";
int i ;
for ( int i = 0; i < G->n; i++ )
visited [i] =FALSE; //标志数组初始化
for ( int i = 0; i < G->n; i++ )
if ( ! visited[i] )
DFS( G, i); //从顶点i 出发开始搜索search() DFSX(G, i )
}
//广度优先遍历
typedef int Elementtype;
struct celltype{
Elementtype element;
celltype *next;
};
struct QUEUE{
celltype *front;
celltype *rear;
};
void MakeNull(QUEUE &Q){
Q.front =new celltype;
Q.front->next =NULL;
Q.rear=Q.front;
}
Boolean Empty(QUEUE Q){
if(Q.front ==Q.rear)
return TRUE;
else
return FALSE;
}
void EnQueue(Elementtype x,QUEUE &Q){
Q.rear->next =new celltype;
Q.rear =Q.rear->next;
Q.rear->element =x;
Q.rear->next =NULL;
}
Elementtype DeQueue(QUEUE &Q){
celltype *tmp;
if(Empty(Q)){
cout<<"queue is empty!\n";
return -1;
}
else{
tmp =Q.front->next;
Q.front->next =tmp->next;
if(Q.front->next ==NULL){
Q.rear =Q.front;
}
return tmp->element;
}
}
void BFS(MTGraph *G, int k)
{
int i , j;
QUEUE Q;
MakeNull(Q);
cout << G->vexlist[ k ]<<" "; //访问vk
visited[ k ] = TRUE; //给vk作访问过标记
EnQueue (k, Q); // vk进队列
while ( ! Empty (Q) ) { //队空时搜索结束
i=DeQueue(Q); //vi出队
for(j=0; j<G->n; j++) { //依次搜索vi的邻接点vj
if ( G->edge[ i ][ j ] ==1 && !visited[ j ]) { //若vj未访问过
cout << G->vexlist[ j ]<<" "; //访问vj
visited[ j ]=TRUE; //给vj作访问过标记
EnQueue ( j , Q ); //访问过的vj入队
}
} //重复检测vi的所有邻接顶点
} //外层循环,判队列空否
} //以vk为出发点时对用邻接矩阵表示的图G进行先广搜索
//广度优先
void BFSTraverse(MTGraph *G)
{
cout<<"\n广度优先搜索结果:\n";
int i ;
for ( int i = 0; i < G->n; i++ )
visited [i] =FALSE; //标志数组初始化
for ( int i = 0; i < G->n; i++ )
if ( ! visited[i] )
BFS( G, i);
}
int main(){
MTGraph *G1 =new MTGraph();
CreateMGraph(G1);
print(G1);
DFSTraverse(G1);
BFSTraverse(G1);
return 0;
}
无向图邻接表DFS/BFS
//无向图邻接表表示法的深度优先和广度优先算法结果
#include <iostream>
using namespace std;
#define NumVertices 11 //顶点个数
#define E 50
#define V 20
typedef char VertexData; //顶点数据类型
typedef int EdgeData; //边上权值类型
typedef struct node { //边表结点
int adjvex; //邻接点域(下标)
//EdgeData cost; //边上的权值
struct node *next; //下一边链接指针
} EdgeNode;
typedef struct { //顶点表结点
VertexData vertex; //顶点数据域
EdgeNode * firstedge; //边链表头指针
} VertexNode;
typedef struct { //图的邻接表
VertexNode vexlist [NumVertices];
int n, e; //图中当前的顶点个数与边数
} AdjGraph;
AdjGraph CreateGraph (AdjGraph *G) {
cout<<"输入顶点个数和边数:";
cin >> G->n >> G->e; //1.输入顶点个数和边数
int i;
int head,tail;
cout<<"输入顶点信息:";
for ( i = 1; i <= G->n; i++) { //2.建立顶点表
cin >> G->vexlist[i].vertex; //2.1输入顶点信息
G->vexlist[i].firstedge = NULL;
} //2.2边表置为空表
cout<<"逐条边输入,建立边表:\n";
for ( i = 1; i <= G->e; i++) { //3.逐条边输入,建立边表
cin >> tail >> head; //3.1输入(变量说明省了)
EdgeNode * p = new EdgeNode; //3.2建立边结点
p->adjvex = head;
p->next = G->vexlist[tail].firstedge; //3.4链入第tail 号链表的前端
G->vexlist[tail].firstedge = p;
p = new EdgeNode;
p->adjvex = tail;
p->next = G->vexlist[head].firstedge; //链入第head 号链表的前端
G->vexlist[head].firstedge = p;
}
return *G;
} //时间复杂度:O(2e+n)
//无向图深度优先遍历
typedef enum{FALSE ,TRUE} Boolean;
Boolean visit[V]; //访问标记数组是全局变量
//顶点的先深编号
void DFS(AdjGraph *G, int i) //以vi为出发点对邻接矩阵表示的图G进行深度优先搜索
{
EdgeNode *p;
cout<<G->vexlist[i].vertex; //访问顶点vi;
visit[i]=TRUE; //标记vi已访问
p=G->vexlist[i].firstedge; //取vi边表的头指针
while( p ) { //依次搜索vi的邻接点vj, 这里j=p->adjvex
if( !visit[p->adjvex] ) //若vj尚未访问
DFS(G, p->adjvex); //则以vj为出发点先深搜索
p=p->next;
}
}//DFS
void DFSTraverse (AdjGraph *G)
//先深搜索一邻接表表示的图G;而以邻接矩阵表示G时,算法完全相同.
{
cout<<"深度优先搜索结果:\n";
int i ;
for ( int i = 1; i <= G->n; i++ )
visit [i] =FALSE; //标志数组初始化
for ( int i = 1; i <= G->n; i++ )
if ( ! visit[i] )
DFS( G, i); //从顶点i 出发开始搜索search() DFSX(G, i )
}
//无向图广度优先遍历
typedef int Elementtype;
struct celltype{
Elementtype element;
celltype *next;
};
struct QUEUE{
celltype *front;
celltype *rear;
};
void MakeNull(QUEUE &Q){
Q.front =new celltype;
Q.front->next =NULL;
Q.rear=Q.front;
}
Boolean Empty(QUEUE Q){
if(Q.front ==Q.rear)
return TRUE;
else
return FALSE;
}
void EnQueue(Elementtype x,QUEUE &Q){
Q.rear->next =new celltype;
Q.rear =Q.rear->next;
Q.rear->element =x;
Q.rear->next =NULL;
}
Elementtype DeQueue(QUEUE &Q){
celltype *tmp;
if(Empty(Q)){
cout<<"queue is empty!\n";
return -1;
}
else{
tmp =Q.front->next;
Q.front->next =tmp->next;
if(Q.front->next ==NULL){
Q.rear =Q.front;
}
return tmp->element;
}
}
void BFS(AdjGraph *G, int k)
{
int i; EdgeNode *p;
QUEUE Q; MakeNull(Q);
cout << G->vexlist[ k ] .vertex;
visit[ k ] = TRUE;
EnQueue (k, Q); //进队列
while ( ! Empty (Q) ) { //队空搜索结束
i=DeQueue(Q); //vi出队
p =G->vexlist[ i ].firstedge; //取vi的边表头指针
while ( p ) { //若vi的邻接点vj (j= p->adjvex)存在,依次搜索
if ( !visit[ p->adjvex ]) { //若vj未访问过
cout << G->vexlist[ p->adjvex ].vertex; //访问vj
visit[ p->adjvex ]=TRUE; //给vj作访问过标记
EnQueue ( p->adjvex , Q ); //访问过的vj入队
}
p = p->next; //找vi的下一个邻接点
} //重复检测vi的所有邻接顶点
} //外层循环,判队列空否
} //以vk为出发点时对用邻接表表示的图G进行先广搜索
//广度优先
void BFSTraverse(AdjGraph *G)
{
cout<<"\n广度优先搜索结果:\n";
int i ;
for ( int i = 1; i <= G->n; i++ )
visit[i] =FALSE; //标志数组初始化
for ( int i = 1; i <= G->n; i++ )
if ( ! visit[i] )
BFS( G, i);
}
void print(AdjGraph *G){
for(int i=1;i<=G->n;i++){
cout<<G->vexlist[i].vertex<<"-->";
EdgeNode *temp =G->vexlist[i].firstedge;
while(temp!=NULL){
cout<<temp->adjvex<<"-->";
temp=temp->next;
}
cout<<"NULL\n";
}
}
int main(){
AdjGraph *g =new AdjGraph();
*g =CreateGraph(g);
print(g);
DFSTraverse(g);
BFSTraverse(g);
return 0;
}