上一篇博文介绍了BFS和DFS的原理,现在给出其JAVA代码实现;
BFS就是维护一个队列,先依次访问起始点相邻的节点,入队,再访问相邻节点的相邻节点,依次入队出队。
DFS就是利用递归+回溯,直到递归到没有相邻节点可以访问了,就向上回溯。
BFS:
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
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
}
}
}
}
}
DFS:
/**
* 建立链表节点
*/
class Node {
int x;
Node next;
public Node(int x) {
this.x = x;
this.next = null;
}
}
public class BinaryTree{
public Node first; //左孩子
public Node last; //右孩子
//保存访问过的节点值
public static int run[] = new int[9];
//建立二叉树节点数组
public static BinaryTree head[] = new BinaryTree[9];
/**
* 访问起始某点,打上标识表示已经访问;再访问这个点的邻接点,在访问这个点的邻接点的邻接点。。一直递归下去,
* 直到没有了邻接点就返回上层继续此操作;每次访问之后就打上标识表示已经访问过;最后找到所有的节点;
* @param current
*/
public static void dfs(int current) {
run[current] = 1;
System.out.print("[" + current + "]");
while (head[current].first != null) {
if(run[head[current].first.x] == 0) { //如果顶点尚未遍历,就进行dfs递归,访问后就是1啦!!!!
dfs(head[current].first.x);
}
head[current].first = head[current].first.next;
}
}
//判断当前节点是否为空
public boolean isEmpty() {
return first == null;
}
public void print() {
Node current = first;
while(current != null) {
System.out.print("[" + current.x + "]");
current = current.next;
}
System.out.println();
}
//插入所有当前节点的所有邻接点;
public void insert(int x) {
Node newNode = new Node(x);
if(this.isEmpty()) {
first = newNode;
last = newNode;
}
else {
last.next = newNode;
last = newNode;
}
}
public static void main(String[] args) {
//这此创建不同于上次的邻接表的创建;这次是直接根据图然后来写出节点对的组合,一对表示是连接在一起的邻接点;
int Data[][] = { {1,2}, {2,1}, {1,3}, {3,1}, {2,4}, {4,2},
{2,5}, {5,2}, {3,6}, {6,3}, {3,7}, {7,3}, {4,5}, {5,4},
{6,7}, {7,6}, {5,8}, {8,5}, {6,8}, {8,6} };
int DataNum;
int i,j;
System.out.println("图形的邻接表内容为:");
for(i=1;i<9;i++) {
run[i] = 0;
head[i] = new BinaryTree();
System.out.print("顶点" + i + "=>");
for (j=0;j<20;j++) {
if(Data[j][0] == i) {
DataNum = Data[j][1];
head[i].insert(DataNum);
}
}
head[i].print();
}
System.out.println("深度优先遍历顶点:");
dfs(1);
System.out.println("");
}
}