(C++)图的深度优先与广度优先遍历

实验内容

输入一个无向图,输出图的深度优先搜索遍历顺序与广度优先搜索遍历顺序。 要求当有多个节点可以搜索时, 优先去节点编号最小的那个。

输入格式:

第一行是两个数 n,m(1<n<30,1<m<300),分别表示顶点数量和边的数量,接下来的 m 行每行输入两个数 a、b;表示顶点 a 与顶点 b 之间有边相连,顶点编号从 1 到 n,最后输入一个数 s 表示遍历的起始顶点编号。

输出格式:

输出两行序列,第一行为深度优先搜索遍历的顺序,第二行为广度优先搜索遍历的顺序。

输入输出样例:

输入样例
5 6
1 5
1 4
3 1
2 1
2 5
5 3
1
输出样例
1 2 5 3 4
1 2 3 4 5

源代码

#include<iostream>
using namespace std;

typedef int VertexType;
#define MaxVexNum 30
#define INFINITY 65535
typedef struct{
    VertexType ves[MaxVexNum+1];//顶点表
    int arc[MaxVexNum+1][MaxVexNum+1];//邻接矩阵
    int VertexNum,EdgeNum;//分别是图中当前顶点数和边数
}MGraph;
int visited[MaxVexNum+1]={0};//记录每个顶点是否被访问过,0为未访问,1为已访问

typedef struct QueueList{
    int vertex;//存顶点序号
    struct QueueList* next;
}Queue;

void CreateMGraph(MGraph &);//创建无向图的邻接矩阵结构
void DFS(MGraph &,int);//深度优先算法(邻接矩阵)
void DFSTraverse(MGraph &,int);//深度优先遍历操作(邻接矩阵)
void BFSTraverse(MGraph &,int);//广度优先遍历操作(邻接矩阵)
void EnQueue(Queue** Q,int n);//把序号为n的顶点入队
int DeQueue(Queue** Q);//将队首顶点出队,返回其序号
int QueueEmpty(Queue *Q);//判断队列是否为空

主函数

int main(){
    MGraph G;
    int a,i;
    CreateMGraph(G);
    cout<<"请输入遍历起始的起始顶点"<<endl;
    cin>>a;
	cout<<"图的深度优先搜索遍历结果是:";
    DFSTraverse(G,a);
    cout<<endl;
    for(i=0;i<=G.VertexNum;i++)
        visited[i]=0;
    cout<<"图的广度优先搜索遍历结果是:";
    BFSTraverse(G,a);
    return 0;
}

创建无向图的邻接矩阵结构

void CreateMGraph(MGraph &G){//创建无向图的邻接矩阵结构
    int i=0,j=0,k=0;
    cout<<"请依次输入顶点数(<30)和边数(<300)"<<endl;
    cin>>G.VertexNum>>G.EdgeNum;
    for(i=1;i<=G.VertexNum;i++)
        G.ves[i]=i;//顶点序号从1开始
    for(i=1;i<=G.VertexNum;i++)
        for(j=1;j<=G.VertexNum;j++){
            if(i==j)
                G.arc[i][j]=0;
            else
                G.arc[i][j]=INFINITY;
        }
    cout<<"每次输入两个顶点序号以表示其间有边相连"<<endl;
    for(k=1;k<=G.EdgeNum;k++){
        cin>>i>>j;
        G.arc[j][i]=G.arc[i][j]=1;   
    }
}

深度优先搜索

void DFS(MGraph &G,int a){//深度优先算法(邻接矩阵)
    int i=0;
    visited[a]=1;
    cout<<G.ves[a];
    for(i=1;i<=G.VertexNum;i++)
        if(G.arc[a][i]==1&&!visited[i])
            DFS(G,i);
}

void DFSTraverse(MGraph &G,int a){//深度优先遍历操作(邻接矩阵)
    int i=0;
    for(i=1;i<=G.VertexNum;i++)
	    visited[i]=0;
    DFS(G,a);
}

队列相关操作

void EnQueue(Queue** Q,int n){//把序号为n的顶点入队
    Queue *p=(Queue*)malloc(sizeof(Queue));
    if(!p)
        printf("申请空间失败");
    p->vertex=n;
    if(!*Q){
        *Q=p;
        (*Q)->next=NULL;
    }
    else{
        Queue* q=*Q;
        while(q->next)
            q=q->next;
        q->next=p;
        p->next=NULL;
    }
}

int DeQueue(Queue** Q){//将队首顶点出队,返回其序号
    if(!*Q)
        return -1;
    int i;
    Queue *p=*Q;
    i=p->vertex;
    *Q=(*Q)->next;
    free(p);
    return i;
}

int QueueEmpty(Queue *Q){//判断队列是否为空
	if(!Q)
		return 1;
	return 0;
}

广度有效搜索

void BFSTraverse(MGraph &G,int a){//广度优先遍历操作(邻接矩阵)
	int i=0,j=0,ver=0;
	for(i=1;i<=G.VertexNum;i++)
		visited[i]=0;
    Queue* Q=NULL;
	visited[a]=1;
	cout<<G.ves[a];
	EnQueue(&Q,a);
	while(!QueueEmpty(Q)){
		i=DeQueue(&Q);
		for(j=1;j<=G.VertexNum;j++){
			if(G.arc[i][j]==1&&!visited[j]){
				visited[j]=1;
				cout<<G.ves[j];
				EnQueue(&Q,j);
			}
		}
	}	
}
  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
C++ 中,我们可以使用邻接表或邻接矩阵来表示,然后采用深度优先搜索或广度优先搜索来遍历。 以邻接表为例,我们可以使用 vector 容器来存储每个节点的邻居节点,如下所示: ```cpp #include <vector> using namespace std; // 邻接表存储 vector<int> graph[N]; // 添加一条从 u 到 v 的有向边 void addEdge(int u, int v) { graph[u].push_back(v); } ``` 然后,我们可以使用递归函数来实现深度优先遍历,如下所示: ```cpp bool visited[N]; // 记录节点是否被访问过 // 深度优先遍历 void dfs(int u) { visited[u] = true; for (int v : graph[u]) { if (!visited[v]) { dfs(v); } } } ``` 在上面的代码中,我们使用 visited 数组来记录每个节点是否被访问过。在遍历节点 u 的邻居节点 v 时,如果节点 v 没有被访问过,则递归调用 dfs(v)。 而对于广度优先遍历,我们可以使用队列来实现。具体来说,我们从起点开始,将其入队,然后依次取出队列中的节点,访问该节点,并将其未访问的邻居节点入队,直到队列为空。如下所示: ```cpp #include <queue> using namespace std; // 广度优先遍历 void bfs(int s) { queue<int> q; bool visited[N] = {false}; q.push(s); visited[s] = true; while (!q.empty()) { int u = q.front(); q.pop(); for (int v : graph[u]) { if (!visited[v]) { visited[v] = true; q.push(v); } } } } ``` 在上面的代码中,我们使用 visited 数组来记录每个节点是否被访问过,使用队列 q 来存储待访问的节点。在遍历节点 u 的邻居节点 v 时,如果节点 v 没有被访问过,则将其入队,并标记为已访问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里澄江

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值