图/树——宽度优先搜索(BFS)

转载

宽度优先搜索(BFS, Breadth First Search)是一个针对图和树的遍历算法。发明于上世纪50年代末60年代初,最初用于解决迷宫最短路径和网络路由等问题。

对于下面的树而言,BFS方法首先从根节点1开始,其搜索节点顺序是1,2,3,4,5,6,7,8。 
《图/树——宽度优先搜索(BFS)》
BFS使用队列(queue)来实施算法过程,队列(queue)有着先进先出FIFO(First Input First Output)的特性,BFS操作步骤如下: 
1、把起始点放入queue; 
2、重复下述2步骤,直到queue为空为止: 
1) 从queue中取出队列头的点; 
2) 找出与此点邻接的且尚未遍历的点,进行标记,然后全部放入queue中。

下面结合一个图(graph)的实例,说明BFS的工作过程和原理: 
(1)将起始节点1放入队列中,标记为已遍历: 
《图/树——宽度优先搜索(BFS)》
(2)从queue中取出队列头的节点1,找出与节点1邻接的节点2,3,标记为已遍历,然后放入queue中。 
《图/树——宽度优先搜索(BFS)》
(3)从queue中取出队列头的节点2,找出与节点2邻接的节点1,4,5,由于节点1已遍历,排除;标记4,5为已遍历,然后放入queue中。 
《图/树——宽度优先搜索(BFS)》
(4)从queue中取出队列头的节点3,找出与节点3邻接的节点1,6,7,由于节点1已遍历,排除;标记6,7为已遍历,然后放入queue中。 
《图/树——宽度优先搜索(BFS)》
(5)从queue中取出队列头的节点4,找出与节点4邻接的节点2,8,2属于已遍历点,排除;因此标记节点8为已遍历,然后放入queue中。 
《图/树——宽度优先搜索(BFS)》
(6)从queue中取出队列头的节点5,找出与节点5邻接的节点2,8,2,8均属于已遍历点,不作下一步操作。 
《图/树——宽度优先搜索(BFS)》
(7)从queue中取出队列头的节点6,找出与节点6邻接的节点3,8,9,3,8属于已遍历点,排除;因此标记节点9为已遍历,然后放入queue中。 
《图/树——宽度优先搜索(BFS)》
(8)从queue中取出队列头的节点7,找出与节点7邻接的节点3, 9,3,9属于已遍历点,不作下一步操作。 
《图/树——宽度优先搜索(BFS)》
(9)从queue中取出队列头的节点8,找出与节点8邻接的节点4,5,6,4,5,6属于已遍历点,不作下一步操作。 
《图/树——宽度优先搜索(BFS)》
(10)从queue中取出队列头的节点9,找出与节点9邻接的节点6,7,6,7属于已遍历点,不作下一步操作。 
《图/树——宽度优先搜索(BFS)》
(11)queue为空,BFS遍历结束。

 

宽度优先搜索用于二叉树遍历:

// 用queue实现的BFS
void BFS(Node *pRoot)
{
	if (pRoot==NULL)
		return;
 
	queue<Node*> Q;
 
	Q.push(pRoot);
 
	while(!Q.empty())
	{
		
		Node *node = Q.front();
 
		cout<<node->nVal<<"->";
		if (node->pLeft!=NULL)
		{
			Q.push(node->pLeft);
		}
 
		if (node->pRight!=NULL)
		{
			Q.push(node->pRight);
		}
 
		Q.pop();
	}
 
	cout<<endl;
}
// temp-test.cpp: 定义控制台应用程序的入口点。
//
#include<iostream>
#include <queue>
#include<stack>
using namespace std;


struct Node
{
	int nVal;
	Node *pLeft;
	Node *pRight;

	Node(int val, Node* left = NULL, Node * right = NULL) :nVal(val), pLeft(left), pRight(right) {}; //构造
};
// 析构
void DestroyTree(Node *pRoot)
{
	if (pRoot == NULL)
		return;

	Node* pLeft = pRoot->pLeft;
	Node* pRight = pRoot->pRight;

	delete pRoot;
	pRoot = NULL;

	DestroyTree(pLeft);
	DestroyTree(pRight);

}


// 用queue实现的BFS
void BFS(Node *pRoot)
{
	if (pRoot == NULL)
		return;

	queue<Node*> Q;

	Q.push(pRoot);

	while (!Q.empty())
	{

		Node *node = Q.front();

		cout << node->nVal << "->";
		if (node->pLeft != NULL)
		{
			Q.push(node->pLeft);
		}

		if (node->pRight != NULL)
		{
			Q.push(node->pRight);
		}

		Q.pop();
	}

	cout << endl;
}


// DFS的递归实现
void DFS_Recursive(Node* pRoot)
{
	if (pRoot == NULL)
		return;

	cout << pRoot->nVal << " ";

	if (pRoot->pLeft != NULL)
		DFS_Recursive(pRoot->pLeft);


	if (pRoot->pRight != NULL)
		DFS_Recursive(pRoot->pRight);

}

// DFS的迭代实现版本(stack)
void DFS_Iterative(Node* pRoot)
{
	if (pRoot == NULL)
		return;

	stack<Node*> S;
	S.push(pRoot);

	while (!S.empty())
	{
		Node *node = S.top();
		cout << node->nVal << ",";

		S.pop();

		if (node->pRight != NULL)
		{
			S.push(node->pRight);
		}

		if (node->pLeft != NULL)
		{
			S.push(node->pLeft);
		}

	}

}


// 打印树的信息
void PrintTree(Node* pRoot)
{
	if (pRoot == NULL)
		return;

	cout << pRoot->nVal << " ";

	if (pRoot->pLeft != NULL)
	{
		PrintTree(pRoot->pLeft);
	}

	if (pRoot->pRight != NULL)
	{
		PrintTree(pRoot->pRight);
	}
}

int main()
{
	Node *node1 = &Node(4);
	Node *node2 = &Node(5);
	Node *node3 = new Node(6);

	Node* node4 = new Node(2, node1, node2);
	Node* node5 = new Node(3, node3);
	Node* node6 = new Node(1, node4, node5);


	Node* pRoot = node6;
	//PrintTree(pRoot);
	//DFS_Recursive(pRoot);
	BFS(pRoot);
	DFS_Iterative(pRoot);
	//DestroyTree(pRoot);

	system("pause");

	return 0;
}

//以上完整版图的深度和广度实例。

    原文作者:BFS
    原文地址: https://blog.csdn.net/Echo1214_Xie/article/details/81672803
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞