圖 深度優先搜索(DFS)、廣度優先搜索(BFS)


1. 深度優先搜索介紹

圖的深度優先搜索(Depth First Search),和樹的先序遍歷比較類似。

它的思想:假設初始狀態是圖中所有頂點均未被訪問,則從某個頂點v出發,首先訪問該頂點,然後依次從它的各個未被訪問的鄰接點出發深度優先搜索遍歷圖,直至圖中所有和v有路徑相通的頂點都被訪問到。 若此時尚有其他頂點未被訪問到,則另選一個未被訪問的頂點作起始點,重複上述過程,直至圖中所有頂點都被訪問到爲止。

顯然,深度優先搜索是一個遞歸的過程。

 

2. 廣度優先搜索介紹

廣度優先搜索算法(Breadth First Search),又稱爲"寬度優先搜索"或"橫向優先搜索",簡稱BFS。

它的思想是:從圖中某頂點v出發,在訪問了v之後依次訪問v的各個未曾訪問過的鄰接點,然後分別從這些鄰接點出發依次訪問它們的鄰接點,並使得“先被訪問的頂點的鄰接點先於後被訪問的頂點的鄰接點被訪問,直至圖中所有已被訪問的頂點的鄰接點都被訪問到。如果此時圖中尚有頂點未被訪問,則需要另選一個未曾被訪問過的頂點作爲新的起始點,重複上述過程,直至圖中所有頂點都被訪問到爲止。

換句話說,廣度優先搜索遍歷圖的過程是以v爲起點,由近至遠,依次訪問和v有路徑相通且路徑長度爲1,2...的頂點。


詳細介紹參考:http://www.cnblogs.com/skywang12345/p/3711483.html


假設圖的分佈如下,分別實現BFS和DFS

                                                        

#include <iostream>
#include <list>
#include <queue>

using namespace std;

class Graph
{
public:
	Graph(int nVertex):m_nVertex(nVertex)
	{
		m_pAdj = new list<int>[nVertex];
	}

	void addEdge(int v,int w);
	void BFS(int vStart);
	void DFS(int vStart);
	

private:
	int m_nVertex;
	list<int> *m_pAdj;

	void CoreDFS(int vStart,bool isVisited[]);
};


void Graph::addEdge(int v,int w)
{
	m_pAdj[v].push_back(w);
}


void Graph::BFS(int vStart)
{
	bool *isVisited = new bool[m_nVertex];
	memset(isVisited,false,m_nVertex);

	queue<int> Q;
	Q.push(vStart);

	isVisited[vStart] =true;
	
	

	while (!Q.empty())
	{
		int n = Q.front();
		cout<<n<<"->";

		for (list<int>::iterator iter=m_pAdj[n].begin();iter!=m_pAdj[n].end();iter++)
		{
			
			if (!isVisited[*iter])
			{
				Q.push(*iter);
				isVisited[*iter] = true;				
			}
			
		}

		Q.pop();
	}

	cout<<endl;
	
}


void Graph::DFS(int vStart)
{
	bool *isVisited = new bool[m_nVertex];
	memset(isVisited,false,m_nVertex);

	CoreDFS(vStart,isVisited);
	
}


void Graph::CoreDFS(int vStart,bool isVisited[])
{
	

	isVisited[vStart]=true;
	cout<<vStart<<"->";

	for (list<int>::iterator iter=m_pAdj[vStart].begin();iter!=m_pAdj[vStart].end();iter++)   //深搜+回溯
	{
		
		if (!isVisited[*iter])
		{
			isVisited[*iter] = true;			
			CoreDFS(*iter,isVisited);
			
		}			
	}

	
	
}


int main()
{
 
	Graph graph(5);  
	graph.addEdge(0, 1);//生成無向圖  
	graph.addEdge(0, 4); 
	graph.addEdge(4, 3);  
	graph.addEdge(4, 0);  
	graph.addEdge(4, 1);  
	graph.addEdge(1, 0);  
	graph.addEdge(1, 4);  
	graph.addEdge(1, 2);  
	graph.addEdge(1, 3);  
	graph.addEdge(2, 1);  
	graph.addEdge(2, 3);  
	graph.addEdge(3, 1);  
	graph.addEdge(3, 4);  
	graph.addEdge(3, 2);  

	
	int vStart=0;

	graph.BFS(vStart);
	graph.DFS(vStart);

	return 0;

}

圖的 DFS非遞歸代碼如下:

每次從棧中彈出一個元素,然後將彈出的設爲已訪問狀態(visited=1),並將彈出元素的所有未被訪問過的鄰接 節點壓入棧中,直到棧爲空爲止。


void DFS_Iterative(int vStart)
{
	bool visited[N];
	memset(visited,false,N);

	stack<int> s;
	s.push(vStart);
	while (!s.empty())
	{
		int w = s.top();
		s.pop();
		if (visited[w]==0)
		{
			cout<<w<<" ";
			visited[w] = 1;
			for (int i=0;i<N;i++)
			{
				if (visited[i]==0 && adj_matrix.edge[w][i]==1)
				{
					s.push(i);
				}
			}
		}
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章