關鍵字:廣度優先,搜索算法,圖論,BFS
廣度優先搜索,即BFS(Breadth First Search),是一種相當常用的圖算法,其特點是:每次搜索指定點,並將其所有未訪問過的鄰近節點加入搜索隊列,循環搜索過程直到隊列為空。
算法描述如下:
(1)將起始節點放入隊列尾部
(2)While(隊列不為空)
取得並刪除隊列首節點Node
處理該節點Node
把Node的未處理相鄰節點加入隊列尾部
使用該算法注意的問題:
(1)使用該算法關鍵的數據結構為:隊列,隊列保證了廣度渡優先,並且每個節點都被處理到
(2)新加入的節點一般要是未處理過的,所以某些情況下最初要對所有節點進行標記
(3)廣度優先在實際使用時,很對情況已超出圖論的範圍,將新節點加入隊列的條件不再局限於
相鄰節點這個概念。例如,使用廣度優先的網絡爬蟲在抓取網頁時,會把一個鏈接指向的網頁中的所有
URL加入隊列供後續處理。
典型實例:
1.圖的遍曆(VC6.0/VS2005)
//////////////////////////////////
//廣度優先之節點遍曆
//1-----5----------9
//| | |
//| | |
//2-----4----6-----8
//| | |
//| | |
//3----------7-----10
// 1 2 3 4 5 6 7 8
//1 0 1 0 0 1 0 0 0
//2 1 0 1 1 0 0 0 0
//3 0 1 0 0 0 0 1 0
//4 0 1 0 0 1 1 0 0
//5 1 0 0 1 0 0 0 0
//6 0 0 0 1 0 0 1 1
//7 0 0 1 0 0 1 0 0
//8 0 0 0 0 0 1 0 0
#include
#include
using namespace std;
//節點數
#define M 10
//圖的矩陣表示
int matrix[M][M] =
{ 0, 1, 0, 0, 1, 0, 0, 0, 0, 0,
1, 0, 1, 1, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
0, 1, 0, 0, 1, 1, 0, 0, 0, 0,
1, 0, 0, 1, 0, 0, 0, 0, 1, 0,
0, 0, 0, 1, 0, 0, 1, 1, 0, 0,
0, 0, 1, 0, 0, 1, 0, 0, 0, 1,
0, 0, 0, 0, 0, 1, 0, 0, 1, 1,
0, 0, 0, 0, 1, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1, 0, 0
};
//訪問標記,初始化為0,
int visited[M + 1];
//graph traverse
void GT_BFS()
{
visited[1] = 1;
queue q;
q.push(1);
while(!q.empty())
{
int top = q.front();
cout << top << " ";//輸出
q.pop();
int i ;
for(i = 1; i <= M; ++i)
{
if(visited[i] == 0 && matrix[top - 1][i - 1 ] == 1)
{
visited[i] = 1;
q.push(i);
}
}
}
}
int main()
{
GT_BFS();//輸出結果為1 2 5 3 4 9 7 6 8 10
system("pause");
return 0;
}
2.有權最短路徑,Dijkstra
///////////////////////////////////////////
//廣度優先搜索之有權最短路徑,Dijkstra算法
// 1---(1)-->5
// | |
//(2) (12)
// | |
// 2--(13)---4---(2)--6--(2)--8
// | |
//(4) (5)
// | |
// 3----(1)----------7
// 1 2 3 4 5 6 7 8
//1 0 2 0 0 1 0 0 0
//2 2 0 4 7 0 0 0 0
//3 0 4 0 0 0 0 1 0
//4 0 7 0 0 12 2 0 0
//5 1 0 0 12 0 0 0 0
//6 0 0 0 2 0 0 5 2
//7 0 0 1 0 0 5 0 0
//8 0 0 0 0 0 2 0 0
#include
#include
using namespace std;
//節點數
#define M 8
//圖的矩陣表示
int matrix[M][M] =
{ 0, 2, 0, 0, 1, 0, 0, 0,
2, 0, 4, 13, 0, 0, 0, 0,
0, 4, 0, 0, 0, 0, 1, 0,
0, 13, 0, 0, 12, 2, 0, 0,
1, 0, 0, 12, 0, 0, 0, 0,
0, 0, 0, 2, 0, 0, 5, 2,
0, 0, 1, 0, 0, 5, 0, 0,
0, 0, 0, 0, 0, 2, 0, 0
};
//保存每個節點的最短路徑,初始化為0xFFFF
int dist[M + 1] ={0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF};
//calculate the distance
void Dijkstra_BFS(int startNodeNum)
{
dist[startNodeNum] = 0;
queue q;
q.push(startNodeNum);
while(!q.empty())
{
int top = q.front();
q.pop();
cout << top << endl;
int i ;
for(i = 1; i <= M; ++i)
{
if(matrix[top - 1][i - 1 ] != 0 && (dist[top] + matrix[top - 1][i -1]) < dist[i] )
{
dist[i] = dist[top] + matrix[top - 1][i -1];
q.push(i);
}
}
}
}
void PrintDist()
{
for(int i = 1; i <= M; ++i)
cout << i << ":" << dist[i] << endl;
}
int main()
{
Dijkstra_BFS(1);
PrintDist();
system("pause");
return 0;
}