图的宽度优先遍历序列

该博客讨论了如何对给定的无向图进行宽度优先遍历(BFS),并给出了以顶点0为起点的BFS序列。输入包括图的顶点数和边数,以及每条边的起点和终点。输出是无向图的邻接矩阵以及从顶点0开始的BFS序列。样例输入和输出展示了具体的图结构和遍历顺序。

题目:

描述

(graph)是数据结构 G=(V,E),其中VG中结点的有限非空集合,结点的偶对称为边(edge)EG中边的有限集合。设V={0,1,2,……,n-1},图中的结点又称为顶点(vertex),有向图(directed graph)指图中代表边的偶对是有序的,用<uv>代表一条有向边(又称为弧),则u称为该边的始点(尾),v称为边的终点(头)。无向图(undirected graph)指图中代表边的偶对是无序的,在无向图中边(uv )(vu)是同一条边。

输入边构成无向图,求以顶点0为起点的宽度优先遍历序列。

输入

第一行为两个整数ne,表示图顶点数和边数。以下e行,每行两个整数,表示一条边的起点、终点,保证不重复、不失败。1≤n≤20,0≤e≤190

输出

前面n行输出无向图的邻接矩阵,最后一行输出以顶点0为起点的宽度优先遍历序列,对于任一起点,按终点序号从小到大的次序遍历每一条边。每个序号后输出一个空格。

样例输入

4 5
0 1
0 3
1 2
1 3
2 3

样例输出

0 1 0 1 
1 0 1 1 
0 1 0 1 
1 1 1 0 
0 1 3 2 


代码:

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;

class Graph
{
private:
	int **a, n, e;//n点,e边
public:
	Graph(int num, int edge);
	~Graph();
	void insert();//插入图的节点
	bool exist(int u, int v);//是否存在(u,v)
	void output();
	void BFS();//深度优先
	void BFS(int v, bool *used);
};

int main()
{
	int n, m;//n点,m边

	cin >> n >> m;
	Graph graph(n, m);
	graph.insert();
	graph.output();
	graph.BFS();
	return 0;
}

Graph::Graph(int num, int edge)
{
	n = num, e = edge;
	a = new int*[n];
	for(int i = 0; i < n; i++)
	{
		a[i] = new int[n];
		memset(a[i], 0, n*sizeof(int));
	}
}

Graph::~Graph()
{
	for(int i = 0; i < n; i++)
	{
		delete []a[i];
	}
	delete []a;
}

void Graph::insert()
{
	int na, nb;
	for(int i = 0; i < e; i++)
	{
		cin >> na >> nb;
		a[na][nb] = 1;
		a[nb][na] = 1;
	}
}

bool Graph::exist(int u, int v)
{
	if(a[u][v]) return true;
	return false;
}

void Graph::BFS()
{
	bool *used = new bool[n];
	int i;
	for(i = 0; i < n; i++)
	{
		used[i] = false;
	}
	for(i = 0; i < n; i++)
	{
		if(!used[i])
		{
			BFS(i, used);
		}
	}
	cout << endl;
	delete []used;
}

void Graph::BFS(int v, bool *used)
{
	queue<int> q;
	cout << v << " ";
	used[v] = true;
	q.push(v);

	while(!q.empty())
	{
		v = q.front();
		q.pop();
		for(int i = 0; i < n; i++)
		{
			if(!used[i] && a[v][i])
			{
				used[i] = true;
				cout << i << " ";
				q.push(i);
			}
		}
	}
}

void Graph::output()
{
	for(int i = 0; i < n; i++)
	{
		for(int j = 0; j < n; j++)
		{
			cout << a[i][j] << " ";
		}
		cout << endl;
	}
}


### 宽度优先遍历与深度优先遍历的区别 #### 算法机制差异 宽度优先遍历BFS)遵循逐层扩展的原则,从起始节点出发,依次访问其所有邻接节点,再按相同方式处理这些新发现的节点直到全部节点被访问完毕[^1]。相比之下,深度优先遍历(DFS)则采取深入探索的方式,在遇到未访问过的分支时会尽可能深地沿着该路径前进直至无法继续为止,随后回溯至上一可选位置并重复此过程。 对于具体实现而言: - **BFS**通常借助队列数据结构完成操作,每次都将当前层次的所有子节点加入到待处理列表末端; - **DFS**更多依赖栈或递归来管理状态转移序列,每当进入新的子树前都会保存现有环境以便后续返回时恢复现场[^3]。 ```python from collections import deque def bfs(graph, start): visited = set() queue = deque([start]) while queue: vertex = queue.popleft() if vertex not in visited: print(vertex) visited.add(vertex) for neighbor in graph[vertex]: if neighbor not in visited: queue.append(neighbor) def dfs(graph, start, visited=None): if visited is None: visited = set() stack = [start] while stack: vertex = stack.pop() if vertex not in visited: print(vertex) visited.add(vertex) stack.extend( neighbor for neighbor in reversed(graph[vertex]) if neighbor not in visited ) ``` #### 应用场景对比 当面对连通性检测、最短路径查找等问题时,由于BFS能够保证首次到达目标节点所经过的距离是最优解之一,故而更适合此类需求;而在涉及拓扑排序、强连通分量识别以及某些特定模式匹配的情况下,则往往更倾向于采用能快速触及深层结构特性的DFS方法[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值