java學習筆記之圖的遍歷(廣度優先搜索BFS)


不知道有沒小伙伴們跟我一樣,在剛開始通過網絡資源學習編程時,拿到大牛們的代碼,總是希望拿到的是可以打印出結果的代碼,但不解的是,大神似乎都不喜歡出示完整代碼(這或許就是英雄所見略同吧偷笑)。我呢,是名編程菜鳥,最近想通過大牛們的經典算法代碼重溫算法和數據結構。本文代碼是來自alibaba的Leo-Yang,網搜了一段時間的BFS\DFS算法理解,個人最喜歡他的圖解解讀,太贊啦!這是他的原文http://www.cnblogs.com/developerY/p/3323264.html,而我呢,在他通熟易懂的圖解幫助下,終於理解BFS啦,同時也在他代碼中注釋了自己對各個函數的理解,並且在stone的幫助下,補充完成了main函數的代碼,這樣就成為看到打印的出結果的完整代碼啦,還望網友們幫忙指正錯誤哈~



package example;


import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
/*廣度遍歷是遍歷到某個頂點,然后訪問其連接點a,b;接着訪問a的連接表,
很自然的,這種數據結構就是HashMap,以頂點為key,保存每個頂點的連接表
*/
public class BFSbak {
public static void main(String args[])
{
BFSbak bb = new BFSbak();
// s頂點的鄰接表
LinkedList<Character> list_s = new LinkedList<Character>();
list_s.add('w');
list_s.add('r');
LinkedList<Character> list_w = new LinkedList<Character>();
list_w.add('s');
list_w.add('i');
list_w.add('x');
LinkedList<Character> list_r = new LinkedList<Character>();
list_r.add('s');
list_r.add('v');
LinkedList<Character> list_x = new LinkedList<Character>();
list_x.add('w');
list_x.add('i');
list_x.add('u');
list_x.add('y');
LinkedList<Character> list_v = new LinkedList<Character>();
list_v.add('r');
LinkedList<Character> list_i = new LinkedList<Character>();
list_i.add('u');
list_i.add('x');
list_i.add('w');
LinkedList<Character> list_u = new LinkedList<Character>();
list_u.add('i');
list_u.add('x');
list_u.add('y');
LinkedList<Character> list_y = new LinkedList<Character>();
list_y.add('u');
list_y.add('x');
HashMap<Character, LinkedList<Character>> graph = new HashMap<Character, LinkedList<Character>>();
graph.put('s', list_s);
graph.put('w', list_w);
graph.put('r', list_r);
graph.put('x', list_x);
graph.put('v', list_v);
graph.put('i', list_i);
graph.put('y', list_y);
graph.put('u', list_u);
HashMap<Character, Integer> dist = new HashMap<Character, Integer>();
char start = 's';
bb.bfs(graph, dist, start);


}
/*HashMap<Character,LinkedList<Character>> graph 
* 這個HashMap是用於存放圖中每個node的鄰接表
* 表示此映射所維護的鍵的類型為Character,此映射值的類型為LinkedList<Character>
* graph 表示將映射關系存放在graph此映射中

* LinkedList<Character> 表示在此Collection中保持元素類型為Character

* HashMap<Character,Integer> dist 
* 這個HashMap 是用於存放每個node與距離頂點s的距離的映射關系
* 表示此映射所維護的鍵的類型為Character
* 此映射所維護的值的類型為Integer,dist表示將映射關系存放到dist此映射中
*/


private void bfs(HashMap<Character, LinkedList<Character>> graph,HashMap<Character, Integer> dist,char start)
{
//Queue<Character> 表示在此Collection中所保存的元素的類型為Character
Queue<Character> q=new LinkedList<Character>();
q.add(start);//將指定元素s插入隊列,成功時返回true,如果沒有可用空間,則返回illegalStateException


/*put(start,0) start為指定值將要關聯的鍵,0為指定值將要關聯的值,
如果start與0的映射關系已存在,則返回並替換舊值0
如果 start與0的映射關系不存在,則返回null 
*/
dist.put(start, 0);


int i=0;
while(!q.isEmpty())//
{
char top=q.poll();//獲取並移除隊列的頭,返回隊列的頭,如果隊列為空,返回null
i++;


//dist.get(top) 返回指定鍵top所映射的值
System.out.println("The "+i+"th element:"+top+" Distance from s is:"+dist.get(top));
int d=dist.get(top)+1;//得出其周邊還未被訪問的節點的距離


/*graph.get(top)如果此映射包含一個滿足 (key==null ? k==null : key.equals(k)) 
的從 k 鍵到 v 值的映射關系,則此方法返回 v;否則返回 null。(最多只能有一個這樣的映射關系。)
for(元素變量:元素集合),如果元素集合中所有元素都已遍歷過,則結束此循環,
否則執行for循環里的程序塊
*/
for (Character c : graph.get(top)) 
{


// containskey(key) 如果此映射包含對於指定鍵key的映射關系,則返回true
if(!dist.containsKey(c))//如果dist中還沒有該元素說明還沒有被訪問
{
/*關聯指定鍵c與指定值d,如果關聯關系已存在,則替換舊值d,返回舊值d,
如果無映射關系,則返回null*/
dist.put(c, d);
q.add(c); //將指定元素c插入隊列,成功時返回true,如果沒有可用空間,則返回illegalStateException
}
}
}
}

}



特別說明下哈,Leo-Yang源代碼里的
Queue<Character> q=new LinkedList<>(); 


不知是否因為我的eclipse是jre1.6緣故,這樣寫是編譯不過的,改成如下就可以啦
Queue<Character> q=new LinkedList<Character>();


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com