图的遍历

连通图:

在无向图G中,如果从顶点v到v'有路径,则称v和v'是连通的。如果对图中任意两点,都是连通的,那么则称图G是连通图。

在有向图G中,如果对于任意一对,vi、vj(不相等),从vi到vj,和从vj到vi都存在路径,则称G是强连通图。

图的遍历:希望从图中某一顶点出发访便图中其余顶点。

注意:如果,从某一点出发,可以遍历所有的顶点,前提就是图的连通性。对于无向图,必须是连通图;对于有向图,必须是强连通图。


广度优先遍历逻辑:放入队列的是还没处理过的顶点,所谓的处理就是针对该顶点指向的其他顶点的操作。

1、将遍历开始的顶点访问标识置为true,压入队列。

2、如果队列不为空,获取队列最前端顶点,弹出该顶点。

3、遍历该顶点指向的顶点,若没有被访问,将其访问标识置为true,压入队列。(一定要注意,在入队列前,要置为true)

4、循环步骤2、3直至队列为空。

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

typedef struct edge  //边结构
{
	int weight;  //边权重
	char adjver; //边指向的顶点
}edge;

typedef struct vertex
{
	char ver;    //顶点存放的元素
	list<edge> edgelis; //顶点发出边的链表
}vertex;

typedef struct graph
{
	int vertexNum;   //图中顶点个数
	vector<vertex> verlis;  //图中顶点数组
	vector<bool> vist;     //辅助图的遍历

	void init()            //主要是对vist初始化
	{
		for (int i = 0; i < vertexNum; i++)
		{
			vist[i] = false;
			verlis[i].ver = 'A' + i;
		}
	}
	graph()
	{
		vertexNum = 0;
	}
	graph(int num)    //构造函数
	{
		vertexNum = num;
		verlis.resize(num);
		vist.resize(num);
		init();   //针对vist数组进行初始化
	}
	void addedge(char ver1, char ver2, int weight) //往图中添加边,记住建立的是有向图
	{
		edge temp1;
		temp1.adjver = ver2;
		temp1.weight = weight;
		verlis[(ver1 - 'A')].edgelis.push_back(temp1);
	}
	void dfs(char a)      //深度优先遍历
	{
		//if (vist[a - 'A']) return;   //可以去掉
		cout << a << " ";
		vist[a - 'A'] = true;

		list<edge>::iterator it = verlis[a - 'A'].edgelis.begin();
		while (it != verlis[a - 'A'].edgelis.end() && !vist[(it->adjver - 'A')])
		{
			dfs(it->adjver);
			it++;
		}
	}
	void bfs(char a)  //广度优先遍历的逻辑是
	{
		queue<char> que;
		vist[a - 'A'] = true;   //压入栈之前,一定要将访问标识为true
		que.push(a);
		while (!que.empty())
		{
			char temp = que.front();
			que.pop();
			cout << temp << " ";
			list<edge>::iterator it = verlis[temp - 'A'].edgelis.begin();
			while (it != verlis[temp - 'A'].edgelis.end())
			{
				if (!vist[(it->adjver - 'A')])
				{
					vist[(it->adjver - 'A')] = true; //压入栈之前,一定要将访问标识为true
					que.push(it->adjver);
				}
				it++;
			}
		}
	}
	void DFS()
	{
		for (int i = 0; i < vertexNum; i++)
		{
			if (!vist[i])
			{
				dfs(verlis[i].ver);
			}
		}
		init();    //针对vist数组进行恢复
	}
	void BFS()
	{
		for (int i = 0; i < vertexNum; i++)
		{
			if (!vist[i])
			{
				bfs(verlis[i].ver);
			}
		}
		init();
	}
}graph;

int main()
{
	char input[15][2] = { { 'A', 'B' }, { 'A', 'F' }, { 'G', 'F' }, { 'B', 'G' }, { 'B', 'C' }, { 'B', 'I' }, { 'C', 'I' }, { 'G', 'D' }, { 'G', 'H' }, { 'F', 'E' }, { 'H', 'E' }, { 'D', 'E' }, { 'H', 'D' }, { 'I', 'D' }, { 'C', 'D' } };
	graph g(9);
	for (int i = 0; i < 15; i++)
	{
		g.addedge(input[i][0], input[i][1], 1);
		g.addedge(input[i][1], input[i][0], 1);
	}
	g.DFS();
	cout << endl;
	g.BFS();
	system("pause");
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值