图的深度优先遍历(DFS)和 广度优先遍历(BFS)

图的深度优先遍历(DFS)

1、深度优先搜索遍历过程

图的深度优先搜索(Depth First Search),和树的先序遍历比较类似。

它的思想:假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然后依次从它的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和v有路径相通的顶点都被访问到。 若此时尚有其他顶点未被访问到,则另选一个未被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。

显然,深度优先搜索是一个递归的过程

深度优先遍历特点是,选定一个出发点后进行遍历,能前进则前进,若不能前进,回退一步再前进,或再回退一步后继续前进。依此重复,直到所有与选定点相通的所有顶点都被遍历。

2、示例
下图的深度优先遍历结果:A B F H C D G I E
下图的广度优先遍历结果:A B C D E F G H I
在这里插入图片描述

创建图(C++)

//图结构体
struct Graph
{
	//顶点的名称
	string vertex[MaxVertex];
	//边的数组
	int edge[MaxVertex][MaxVertex];
	//顶点的数量
	int vertexNum;
	//边的数量
	int edgeNum;
};

int LocalVertex(Graph g, string name)
{
	for (int i = 0; i < g.vertexNum; ++i)
	{
		if (g.vertex[i] == name)
		{
			return i;
		}
	}
	return -1;
}

//创建图
void CreateGraph(Graph &g)
{
	cout << "请输入顶点和边的数量:" << endl;
	cin >> g.vertexNum >> g.edgeNum;
	cout << "请输入" << g.vertexNum << "个顶点的名称:" << endl;
	for (int i = 0; i < g.vertexNum; ++i)
	{
		cin >> g.vertex[i];
	}
	//初始化
	for (int i = 0; i < g.vertexNum; ++i)
	{
		for (int j = 0; j < g.vertexNum; ++j)
		{
			g.edge[i][j] = 0;
		}
	}
	cout << "请输入" << g.edgeNum << "条边,顶点1 顶点2" << endl;
	string v1, v2;
	for (int i = 0; i < g.edgeNum; ++i)
	{
		cin >> v1 >> v2;

		int m = LocalVertex(g, v1);
		int n = LocalVertex(g, v2);

		g.edge[m][n] = 1;
		g.edge[n][m] = 1;
	}
}

DFS代码(C++)

非递归遍历(有向图和无向图的DFS代码都一样)
需要用到栈

//深度优先遍历
void DFS(Graph g)
{
	bool* visit = new bool[g.vertexNum];//标记顶点是否被访问过
	for (int i = 0; i < g.vertexNum; ++i)
	{
		visit[i] = false;
	}

	//从顶点的第一个开始访问
	stack<int> st;
	visit[0] = true;
	cout << g.vertex[0] << " ";
	st.push(0);

	while (!st.empty())
	{
		for (int i = 0; i < g.vertexNum; ++i)
		{
			int top = st.top();
			if (!visit[i] && g.edge[top][i] > 0)
			{
				visit[i] = true;
				cout << g.vertex[i] << " ";
				st.push(i);
			}
		}
		st.pop();
	}
	delete[]visit;
	cout << endl;
}

递归遍历
v 是顶点所在所在数组中的位置

void DFS(int v)
{
    int n=vertexNum;//顶点数目
    if(v<0||v>=n) throw "位置出错";
    cout<<vertex[v]<<" ";//输出顶点v
    visited[v]=1;//被访问过
    for(int j=0;j<n;j++)
        if(visited[j]==0&&adj[v][j]==1)//没被访问过且存在边(v,j)
            DFS(j);
}

BFS代码(C++)

需要用到队列

//广度优先遍历
void BFS(Graph g)
{
	bool* visit = new bool[g.vertexNum];
	queue<int> queue;
	//初始化所有顶点的状态
	for (int i = 0; i < g.vertexNum; ++i)
	{
		visit[i] = false;
	}
	visit[0] = true;
	cout << g.vertex[0] << " ";
	queue.push(0);

	while (!queue.empty())
	{
		int top = queue.front();
		queue.pop();
		for (int i = 0; i < g.vertexNum; ++i)
		{
			if (!visit[i] && g.edge[top][i] > 0)
			{
				visit[i] = true;
				cout << g.vertex[i] << " ";
				queue.push(i);
			}
		}
	}
	delete[] visit;
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值