java学习笔记之图的遍历(广度优先搜索BFS)

不知道有没小伙伴们跟我一样,在刚开始通过网络资源学习编程时,拿到大牛们的代码,总是希望拿到的是可以打印出结果的代码,但不解的是,大神似乎都不喜欢出示完整代码(这或许就是英雄所见略同吧《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>();

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/samnancy/article/details/42214719
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞