关闭

图的广度优先搜索

标签: graphtraversaliteratorlistclass存储
2191人阅读 评论(1) 收藏 举报
分类:

      图的广度优先搜索基本思想和树的层次遍历差不错。与树的层次遍历不同的是,图中可能包含回路,我们遍历完一个节点,继续进行遍历,可能会回到已经遍历过的节点。为了避免遍历一个节点两次,需要开辟一个bool型的数组来标记该节点是否已经遍历过。

      例如,在下图中,我们从节点2开始遍历,当我们到达节点0以后,继续寻找节点0的邻接点,节点2也是节点0的邻接点。如果我们不对已经遍历过的节点做任何标记,节点2就会再次被遍历,从而让我们陷入死循环。下图的广度优先搜索结果是:2,0,3,1


      下面是用C++实现的一个简单的广度优先搜索。图的存储方式采用的是邻接表,用list容器来保存图中的边,程序中还用到了队列。

程序如下:

//Program to print BFS traversal from a given source vertex. BFS(int s)
//Traverses vertices reachable from s.
#include <iostream>
#include <list>
#include <queue>
using namespace std;

//This class represents a directed graph using adjacency list representation
class Graph
{
private:
	int v;// Number of vertices
	list<int> *adj;//Pointer to an array containing adjacency lists
public:
	Graph(int v);//Constructor
	void addEdge(int v, int w);//function to add an edge to graph
	void BFS(int s);//prints BFS tracersal from a given sources
};

Graph::Graph(int v)
{
	this->v = v;
	adj = new list<int>[v];
}
void Graph::addEdge(int v, int w)
{
	adj[v].push_back(w);//Add w to v's list
}
void Graph::BFS(int s)
{
	//Mark all the vertices as not visited
	bool *visited = new bool[v];
	for(int i = 0; i < v; i++)
	{
		visited[i] = false;
	}
	
	//Create a queue for BFS
	list<int> queue;

	//Mark the current node as visited and enqueue it
	visited[s] = true;
	queue.push_back(s);

	//i will be used to get all adjacent vertices fo a vertex
	list<int>::iterator i;
	while( !queue.empty() )
	{
		//Dequeue a vertex from queue and print it
		s = queue.front();
		cout << s << " ";
		queue.pop_front();

		//Get all adjacent vertices of the dequeued vertex s
		//If a adjacent has not been visited, then mark it visited
		//and enqueue it
		for( i = adj[s].begin(); i != adj[s].end(); i++)
		{
			if( !visited[*i] )
			{
				visited[*i] = true;
				queue.push_back(*i);
			}
		}
	}
	cout << endl;
}


//Driver program to test methonds of graph class
int main(int argc, char* argv[])
{
	//Create a graph given in the above diagram
	Graph g(4);
	g.addEdge( 0, 1);
	g.addEdge( 0, 2);
	g.addEdge( 1, 2);
	g.addEdge( 2, 0);
	g.addEdge( 2, 3);
	g.addEdge( 3, 3);

	cout <<"Followint is Breadth First Travesal( starting from vertex 2 )\n";
	g.BFS(2);
	return 0;
}

输出(下面是以节点2为起点的广度优先搜索的结果):

Following is Breadth First Traversal ( starting from vertex 2)

2 0 3 1

    注意,上面的程序只能遍历从起始节点可达的节点。对于非连通图中的一些不可达的节点则不能遍历到。

原文网址:http://www.geeksforgeeks.org/archives/18382?utm_source=rss&utm_medium=rss&utm_campaign=breadth-first-traversal-for-a-graph

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:726793次
    • 积分:7863
    • 等级:
    • 排名:第2747名
    • 原创:133篇
    • 转载:35篇
    • 译文:7篇
    • 评论:118条
    声明
    本博客乃学习笔记,没有纯粹无意义的转载。作者除了对自己负责,不对任何读者负责。欢迎指出文章错误,如果原意交朋友,可以通过Gmail联系我(mingxinglai#gmail.com),博客基本不再更新,欢迎访问我的独立博客http://mingxinglai.com
    文章分类
    最新评论