图及其遍历(邻接矩阵)

图及其遍历(邻接矩阵)

例题

建立无向图G的邻接矩阵存储结构,求其从任意顶点出发的广度优先搜索序列与深度优先搜索序列。(每个点优先去往周围未到达的点中编号最小的点)

输入格式:
第一行两个正整数n, m表示G中顶点数与边数
接下来m行每行两个正整数u,v表示u点与v点之间有一条无向边
若同一条边被输入两次,则自动增加一行输入 (1 <= u, v, w <= n) (1 <= n <= 500, 1 <= m <= 2000)
最后一行一个正整数w表示遍历的起始顶点

输出格式:
第一行n个正整数表示广度优先搜索序列
第二行n个正整数表示深度优先搜索序列 (若输入的起始顶点不存在,则不输出顶点搜索序列,输出“起始顶点不存在”)

样例输入:
5 10 1 2 1 3 2 4 4 5 1 3 1 4 2 5 2 3 3 5 1 5 3 4 1 (其中1 3 重复输入)

样例输出:
1 2 3 4 5 1 2 3 4 5

解题思路

首先得构建邻接矩阵,因此直接在main函数中构建

int main() {
	int n, m;
	cin >> n >> m;
	vector<vector<int>>adjMatrix(n + 1, vector<int>(n + 1, 0));
	vector<bool>visited(n + 1, false);

	for (int i = 0; i < m; ++i) {
		int u, v;
		cin >> u >> v;
		if (adjMatrix[u][v] == 1 || adjMatrix[v][u] == 1) {
			i--;
		}
		else {
			adjMatrix[u][v] = 1;
			adjMatrix[v][u] = 1;
		}
	}
	int w;
	cin >> w;
	if (w > n)
		cout << "起始顶点不存在";
	else {
		bfs(w, adjMatrix, visited);
		fill(visited.begin(), visited.end(), false);
		dfs(w, adjMatrix, visited);
	}
	return 0;

}

在以上程序中,先构建了一个相当于矩阵的容器adjMatrix,又来表示邻接矩阵,之后构建visited容器,用来储存各个节点的布尔值,之后运用for循环,更新矩阵里的值,之后就一次进行广度和深度的优先遍历
首先进行广度优先遍历

void bfs(int start, const vector<vector<int>>&adjMatrix,vector<bool>&visited) {
	queue<int>q;
	q.push(start);
	visited[start] = true;
	while (!q.empty()) {
		int current = q.front();
		q.pop();
		cout << current << " ";
		for (int i = 1; i < adjMatrix.size(); ++i) {
			if (adjMatrix[current][i] && !visited[i]) {
				q.push(i);
				visited[i] = true;
			}
		}
	}
	cout << endl;
}

在广度优先遍历中,同样构建队列来储存遍历过程中的节点,先将开始节点装入队列,之后将该节点的布尔值改为true,然后进入循环,当队列为空时,退出循环
在循环中,先将队列中最前面的元素取出,并将其赋值给current,然后依次遍历矩阵中第current行的元素,将其布尔值为false的装入队列中,之后将这些节点的布尔值改为true,防止之后的循环将同样的节点值装入队列中,进入下一轮循环,由此可形成广度优先遍历

之后进行深度优先遍历
先写一个辅助函数

void dfsUtil(int index, const vector<vector<int>>& adjMatrix, vector<bool>& visited) {
	visited[index] = true;
	cout << index << " ";
	for (int i = 1; i < adjMatrix.size(); ++i) {
		if (adjMatrix[index][i] && !visited[i]) {
			dfsUtil(i, adjMatrix, visited);
		}
	}
}

在深度优先遍历中,和前面邻接表的;类似,都是依次递归调用遍历当前节点的邻接节点
先将当前节点的布尔值改为true,之后输出当前节点,之后进入for循环依次对矩阵第index行每个布尔值为false的邻接点进行深度遍历
之后进行深度遍历

void dfs(int start, const vector<vector<int>>& adjMatrix, vector<bool>& visited) {
	dfsUtil(start, adjMatrix, visited);
	cout << endl;
}

同样在这个函数中,调用辅助函数,完成深度优先遍历

运行结果示例

案例

10 40
1 2
2 3
1 4
2 5
1 6
5 7
5 8
3 9
9 10
2 10
4 8
2 4
6 7
3 6
5 9
4 7
8 10
6 8
4 6
1 10
8 9
1 7
4 5
2 9
3 7
7 8
2 8
2 6
7 10
3 10
2 7
3 4
1 8
5 10
5 6
3 5
4 9
6 10
3 8
1 5
1

结果

1 2 4 5 6 7 8 10 3 9
1 2 3 4 5 6 7 8 9 10

库名

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

这篇文章可对应之前发的邻接表看更容易理解
刚学不久,如果有哪里不对,恳请各位师傅指教!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值