广度优先搜索和深度优先搜索

DBF深度优先搜索,最经典的方法,可以使用递归来实现。

结构体定义

typedef char VertexType;
typedef int EdgeType;
#define MAXVEX 100
#define INFINITE 65535
typedef struct  
{
	VertexType vexs[MAXVEX];	//顶点表
	EdgeType arc[MAXVEX][MAXVEX];	//邻接矩阵
	int numVertexes,numEdges;
}MGraph;

测试函数如下


	MGraph graph;
	graph.numVertexes = 9;
	graph.numEdges = 14;
	graph.vexs[0] = 'A';
	graph.vexs[1] = 'B';
	graph.vexs[2] = 'C';
	graph.vexs[3] = 'D';
	graph.vexs[4] = 'E';
	graph.vexs[5] = 'F';
	graph.vexs[6] = 'G';
	graph.vexs[7] = 'H';
	graph.vexs[8] = 'I';
		
	for (int i = 0;i<MAXVEX;i++)
		for (int j= 0;j<MAXVEX;j++)

	{
		graph.arc[i][j] = INFINITE;
	}
	graph.arc[0][1] = graph.arc[1][0] = 1;
	graph.arc[0][5] = graph.arc[5][0] = 1;
	graph.arc[1][2] = graph.arc[2][1] = 1;
	graph.arc[1][8] = graph.arc[8][1] = 1;
	graph.arc[1][6] = graph.arc[6][1] = 1;
	graph.arc[2][8] = graph.arc[8][2] = 1;
	graph.arc[2][3] = graph.arc[3][2] = 1;
	graph.arc[3][8] = graph.arc[8][3] = 1;
	graph.arc[5][6] = graph.arc[6][5] = 1;
	graph.arc[4][5] = graph.arc[5][4] = 1;
	graph.arc[6][7] = graph.arc[7][6] = 1;
	graph.arc[4][7] = graph.arc[7][4] = 1;
	graph.arc[3][7] = graph.arc[7][3] = 1;
	graph.arc[3][6] = graph.arc[6][3] = 1;
	
	printf("DFS by recursion\n");
	solu.DeepthFirstSearch(graph);

	printf("\nDFS by Stack\n");
	solu.DeepthFirstSearch_Stack(graph);

	printf("\nBFS by Quene\n");
	solu.BreadthFirstSearch(graph);

用递归实现的代码如下

	 int visited[MAXVEX];
	 void DFS(MGraph graph, int i)
	 {
		 printf("%c ",graph.vexs[i]);
		 visited[i]=1;
		 for (int j = 0;j<graph.numVertexes;j++)
		 {
			 if (graph.arc[i][j]!=INFINITE && visited[j]==0)
			 {
				 DFS(graph,j);
			 }
		 }
	 }

	 void DeepthFirstSearch(MGraph graph)
	 {
		 for (int i = 0;i<graph.numVertexes;i++)
		 {
			 visited[i] = 0;//未被访问
		 }
		 for (int i = 0; i<graph.numVertexes; i++)
		 {
			 if (visited[i] == 0)
			 {
				 DFS(graph,i);
			 }
		 }
	 }

同样也可以使用栈来实现

	 void DeepthFirstSearch_Stack(MGraph graph)
	 {
		 for (int i = 0;i<graph.numVertexes;i++)
		 {
			 visited[i] = 0;//未被访问
		 }
		 stack<int> stackDFS;
		 for (int i = 0; i<graph.numVertexes; i++)
		 {
			if (visited[i] == 0)
			{
				visited[i] = 1;
				stackDFS.push(i);
			
				while (!stackDFS.empty())
				{
					int k = stackDFS.top();
					visited[k] = 1;
					printf("%c ",graph.vexs[k]);
					stackDFS.pop();
					for (int j = 0; j<graph.numVertexes ;j++)
					{
						if (graph.arc[k][j] != INFINITE && visited[j] == 0)
						{
							visited[j] = 1;
							stackDFS.push(j);
						}
					}
				}
			}
		 }
	 }

而广度优先搜索可以使用队列来实现

	 void BreadthFirstSearch(MGraph graph)
	 {
		 for (int i = 0;i<graph.numVertexes;i++)
		 {
			 visited[i] = 0;//未被访问
		 }
		 queue<int> QueueBFS;
		 for (int i = 0;i<graph.numVertexes;i++)
		 {
			if (visited[i] == 0)
			{
				visited[i] = 1;
				QueueBFS.push(i);
			
			while (!QueueBFS.empty())
			{
				int k = QueueBFS.front();
				printf("%c ",graph.vexs[k]);

				QueueBFS.pop();
				for (int j = 0;j<graph.numVertexes;j++)
				{
					if (graph.arc[k][j] != INFINITE && visited[j] == 0)
					{
						visited[j] = 1;
						QueueBFS.push(j);
					}
				}
			}
		 }		 
		}
	 }

运行结果如下图



可以看到,二者代码几乎一毛一样。区别在于DFS使用了栈,BFS使用的是队列。其实结合DFS和BFS的特点也很好理解,从树的角度思考,BFS希望先找到左右的子节点,希望按照这个顺序来打印,所以就是先进先出,也就是队列。而DFS则希望先顺着某条线一直打印,希望后进的先打印出来,也就是栈。

注意,两种DFS打印结果是不一样的,但是都是DFS。

最后需要注意的是,用栈和队列写这两个算法时,打印的位置很重要,自己写容易出错,不知道是在visit[i]=1的时候就打印还是出队列的时候打印。其实很简单,我们利用的就是栈和队列的特色,所以出栈和出队列的时候打印就没有问题了。





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值