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);
}
}
}
}
}