利用DFS遍历有向图

 BFS:总是先搜索距离初始状态近的状态,利用队列进行运算。 
  DFS:从某个状态开始,不断转移状态到无法转移为止,然后退回到前一步,继续转移到其他状态,不断重复,直至找到最终的解。
  BFS与DFS两种都能生成所有遍历状态,但是要求对所有状态进行处理时使用DFS比较方便;在求最短路径用BFS比较好。 
  以下使用图的遍历算法来举例说明。
DFS
基本流程
深度优先搜索在搜索过程中访问某个顶点后,需要递归地访问此顶点的所有未访问过的相邻顶点。
初始条件下所有节点为白色,选择一个作为起始顶点,按照如下步骤遍历:
a. 选择起始顶点涂成灰色,表示还未访问
b. 从该顶点的邻接顶点中选择一个,继续这个过程(即再寻找邻接结点的邻接结点),一直深入下去,直到一个顶点没有邻接结点了,涂黑它,表示访问过了
c. 回溯到这个涂黑顶点的上一层顶点,再找这个上一层顶点的其余邻接结点,继续如上操作,如果所有邻接结点往下都访问过了,就把自己涂黑,再回溯到更上一层。
d. 上一层继续做如上操作,知道所有顶点都访问过。

图的DFS基本步骤

ç®æ å¾

如图,从顶点1开始做深度搜索:

初始状态,从顶点1开始
依次访问过顶点1,2,3后,终止于顶点3
从顶点3回溯到顶点2,继续访问顶点5,并且终止于顶点5
从顶点5回溯到顶点2,并且终止于顶点2
从顶点2回溯到顶点1,并终止于顶点1
从顶点4开始访问,并终止于顶点4
DFS也可以先访问读取到的结点,等回溯时就不再输出该结点。
 

思路: 首先利用二维数组记录 有向图的线

int maze[N][N] =  //用来表示有向图的边  即不同节点的转换关系
{
    {0,1,1,0,0},
    {0,0,1,0,1},
    {0,0,1,0,0},
    {1,1,0,0,1},
    {0,0,1,0,0}
};

然后,利用一维数组记录 节点是否被访问 如果被访问 数组对应的索引置为1

int visited[N + 1] = { 0 };

 

依次以图中的节点作为 头 压入栈中。然后构建函数DFS。

DFS函数中,如果栈为空,那么停止,否则,依次取出栈顶的数去maze中查找子节点,如果子节点存在那么,压入栈中,并去寻找这个子节点的子节点。

如果,某个节点没有子节点,即在maze中没有找到,那么,打印节点 并从栈中将节点删除。

 

 

非递归的代码

#include<iostream>
#include<stack>

using namespace std;
#define N 5

int maze[N][N] =  //用来表示有向图的边  即不同节点的转换关系
{
	{0,1,1,0,0},
	{0,0,1,0,1},
	{0,0,1,0,0},
	{1,1,0,0,1},
	{0,0,1,0,0}
};
int visited[N + 1] = { 0 };

//非递归
void DFS(int start)
{
	stack<int> s;
	s.push(start); //首先将头放进stack中
	visited[start] = 1;
	bool is_push = false;//标志位 用来判断是否深度搜索完 如果其为true 表示 找到子节点 false 表示没有子节点 则该节点 就是深度搜索的尾
	while (!s.empty())
	{
		int v = s.top();
		bool is_push = false;
		for (int j = 1; j <= N; j++)
		{
			if (maze[v - 1][j - 1] == 1 && visited[j] == 0)
			{
				s.push(j);
				visited[j] = 1;
				is_push = true;
				break;
			}
		}
		if (!is_push)
		{
			cout << v << endl;
			s.pop();
		}
	}


}



int main()
{
	for (int i = 1; i <= N; i++)//依次以i为头结点进行深度搜索
	{
		if (visited[i] == 1)
		{
			continue;
		}
		DFS(i);
		
	}
	system("pause");
	return 0;
}

递归的代码:

#include<iostream>
#include<stack>

using namespace std;
#define N 5

int maze[N][N] =  //用来表示有向图的边  即不同节点的转换关系
{
	{0,1,1,0,0},
	{0,0,1,0,1},
	{0,0,1,0,0},
	{1,1,0,0,1},
	{0,0,1,0,0}
};
int visited[N + 1] = { 0 };

//递归
void DFS(int start)
{
	visited[start] = 1;
	for (int j = 1; j <= N; j++)
	{
		if (maze[start - 1][j - 1] == 1 && visited[j] == 0)
		{
			DFS(j);
		}
	}
	cout << start << endl;
	
}



int main()
{
	for (int i = 1; i <= N; i++)//依次以i为头结点进行深度搜索
	{
		if (visited[i] == 1)
		{
			continue;
		}
		DFS(i);
		
	}
	system("pause");
	return 0;
}

 

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值