图论(一) 图的DFS与BFS


图论系列文章

图论(一) 图的DFS与BFS

图论(二) 最短路径:Dijkstra算法与Floyd算法

图论(三)最小生成树:Prim算法与Kruskal算法

图论(四)拓扑排序与关键路径


前言

图根据其几种属性可以进行分类:

  1. 根据边有没有方向:有向图 无向图
  2. 根据边有没有加权:加权图 非加权图
  3. 根据图是否连通:连通图 非连通图
  • 无向图实质上就是相互指向的有向图
  • 非加权图实质上就是权值全部为1的加权图

图的数据结构存储方式,常用的方式有两种,邻接表邻接矩阵,初学者刚开始的时候并不了解这两种存储方式的区别,而实际上这两种方式实质上在操作中基本上是一样的,只是vector中存储元素的遍历方式不同而已。

  • 邻接矩阵
vector<vector<int>> vertex;
  • 邻接表
vector<list<int>> vertex;

接下来的操作,都将以下图的 图作为标准进行实验。

在这里插入图片描述

  • graph.conf
7 10
0 1 
0 2 
1 3 
2 3 
1 4 
3 4 
3 5 
2 5 
4 6 
5 6 

一.DFS递归遍历

int N, C;//N个顶点,C条边
void DFS(vector<vector<int>>& vertex, vector<int>& visited, int i)
{
	if (visited[i])
		return;
	cout << i << "->";
	visited[i] = 1;
	for (int j = 0; j < N; ++j)
	{
		if (0 == vertex[i][j])//如果不连通
			continue;
		DFS(vertex, visited, j);
	}
}

int main()
{
	cin >> N >> C;
	vector<vector<int>> vertex(N, vector<int>(N, 0));
	for (int i = 0; i < C; ++i)
	{
		int m, n;
		cin >> m >> n;
		vertex[m][n] = 1;//顶点m到顶点n连通
	}
	
	//DFS递归法测试
	vector<int> visited(N, 0);
	//该图可能是非连通的,所有需要遍历每一个点
	for (int i = 0; i < N; ++i)
	{
		if (visited[i])
			continue;
		DFS(vertex, visited, i);
	}
	cout << endl;
	return 0;
}


二.DFS非递遍历

int N, C;//N个顶点,C条边
void DFS(vector<vector<int>>& vertex, vector<int>& visited, int start)
{
	stack<int> stk;
	stk.push(start);
	while (!stk.empty())
	{
		int i = stk.top();
		visited[i] = 1;
		cout << i << "->";
		stk.pop();
		for (int j = 0; j < N; ++j)
		{
			if (0 == vertex[i][j] || visited[j])//不连通或者已经访问过
				continue;
			stk.push(j);
		}
	}
	cout << endl;
}

int main()
{
	cin >> N >> C;
	vector<vector<int>> vertex(N, vector<int>(N, 0));
	for (int i = 0; i < C; ++i)
	{
		int m, n;
		cin >> m >> n;
		vertex[m][n] = 1;//顶点m到顶点n连通
	}

	//DFS递归法测试
	vector<int> visited(N, 0);
	//该图可能是非连通的,所有需要遍历每一个点
	for (int i = 0; i < N; ++i)
	{
		if (visited[i])
			continue;
		DFS(vertex, visited, i);
	}
	cout << endl;
	return 0;
}


三.BFS遍历


int N, C;//N个顶点,C条边
void BFS(vector<vector<int>>& vertex, vector<int>& visited, int start)
{
	queue<int> que;
	que.push(start);
	visited[start] = 1;
	while (!que.empty())
	{
		queue<int> tQue;
		while (!que.empty())
		{
			int i = que.front();
			que.pop();
			cout << i << "->";
			for (int j = 0; j < N; ++j)
			{
				if (0 == vertex[i][j] || visited[j])//不连通或者已经访问过
					continue;
				tQue.push(j);
				visited[j] = 1;
			}
		}
		swap(que, tQue);
	}
}

int main()
{
	cin >> N >> C;
	vector<vector<int>> vertex(N, vector<int>(N, 0));
	for (int i = 0; i < C; ++i)
	{
		int m, n;
		cin >> m >> n;
		vertex[m][n] = 1;//顶点m到顶点n连通
	}

	//从某一点开始BFS遍历
	vector<int> visited(N, 0);
	BFS(vertex, visited, 0);

	return 0;
}


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值