廣度優先遍歷(breadth-first traverse,bfts),稱作廣度優先搜索(breath first search)是連通圖的一種遍歷策略。之所以稱作廣度優先遍歷是因為他的思想是從一個頂點V0開始,輻射狀地優先遍歷其周圍較廣的區域。
算法描述
給定圖G=(V,E)。V是節點集合,E是邊集合。 設定一個訪問標志位vflag(i)表示節點i的訪問情況,若vflag(i)=0表示節點i未被訪問 vflag(i)=1表示節點i已經被訪問過。 l 初始化所有節點的vflag=0。 l 從圖中某個節點V0出發(該節點可以是任意的),並訪問此頂點。 l 從V0出發,訪問V0的各個未曾訪問的鄰接點(下標從小到大排列)W1,W2,…,Wk;然后,依次從W1,W2,…,Wk出發訪問各自未被訪問的鄰接點。 l 重復上步,直到全部頂點都被訪問為止。 |
For example,
fig1. 5節點無向圖
假設我們先從V3 節點開始,把V3裝進遍歷結果隊列和緩存隊列。將V3訪問標志位置1。取出緩存隊列首位后並丟棄。這里是V3節點。找出與V3節點相鄰的並未被訪問過的節點有。有V1和V5節點,按下標大小我們將V1和V5分別裝進緩存隊列和遍歷隊列。自此。緩存隊列是[1,5]。遍歷隊列是[3,1,5]。此時緩存隊列沒有丟空,我們繼續重復之前的步驟。即取出並丟棄緩存隊列隊首V1。找出與V1相鄰並未訪問過的節點,有V2,V4.. 此時緩存隊列是[5,2,4],遍歷隊列是[3,1,5,2,4]。此時,已經完成遍歷。緩存隊列還未被丟空,繼續重復上述步驟。即取出並丟棄緩存隊列隊首V5,找出與V5相鄰未被訪問的節點,沒有。V3相鄰但是V3已被訪問。此時緩存隊列是[2,4],遍歷隊列是[3,1,5,2,4]。類似丟V2,V4直至緩存隊列丟空。實際為節省程序運行時間可將遍歷結束條件設為訪問標志隊列全部非0。
BFT的java實現代碼:
2 % 文件名: bfst 3 % 版本號: 1.0.0 4 % 作者: Isabelle<isabellezhou@163.com> 5 % 單位: specter 6 % 修改時間: Sat Oct. 8 1:20:01 2017 7 % 創建時間: Sat Oct. 8 1:20:01 2017 8 %-------------------------------------------------------------------------- 9 % blog:http://www.cnblogs.com/isabellezhou 10 % Copyright (Dist) 2017 Isabelle All rights reserved. 11 %============================================
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
public class BST{
public static void main(String[] args){
int[][] A=new int[][]{{0,1,1,1,0},{1,0,0,1,0},{1,0,0,0,1},{1,1,0,0,0},{0,0,1,0,0}};
int n=A.length; //元素個數
ArrayList<Integer> result=new ArrayList<Integer>();
Queue<Integer> thequeue = new LinkedList<Integer>(); //LinkedLis實現queue接口
boolean[] marked=new boolean[n]; //marked[i]標記是否被遍歷過,遍歷過為true
for (int i = 0; i < n; i++) {
marked[i] = false; //初始化標記數組
}
int startNode=3; //搜索起始結點
thequeue.offer(startNode); //起始結點裝入隊列
result.add(startNode); //起始結點裝入遍歷數組
marked[startNode]=true; //更新起始結點的訪問標志
while(!thequeue.isEmpty()){ //隊列非空
int v1=(int)thequeue.poll();
for (int k= 0; k<n; k++) {
if (A[v1][k]>0&&marked[k]==false&&v1!=k) {
thequeue.offer(k); //壓入隊列
marked[k] = true; //更新訪問標志位
result.add(k); //更新遍歷數組
}
}
}
System.out.println(result);
}
}
這里所舉的例子,圖的存儲方式都是鄰接矩陣,查找每個結點所需時間為O(|V|)(注:V為頂點數),所以算法總的時間復雜度為O(|V|^2)。