BFS&DFS总结

刷题经常会碰到,在这里总结一下


BFS、DFS 原理

BFS: 广度优先搜索
DFS: 深度优先搜索
树的 BFS 相当于层次遍历这里主要说一下图的遍历,如下图:
1
从 A 开始进行 BFS 的过程:

  1. 首先和 A 相连的有 B、C,遍历序列为:A B C
  2. 然后再依次判断下一个点如 B、C ,相连的且不重复的点,遍历序列为:A B C D E
  3. 重复 2 操作,BFS 序列为:A B C D E F
    同样如果从 E 开始,则序列为:E C D A B F 或者 E D C B F A(不唯一)

BFS 的过程可用队列来描述:

  1. 刚开始 A 入队列,然后 A 出队,与 A 相连的 B、C 入队
  2. 然后 B 出队,与 B 相连且队中没有的入队,即 D
  3. 重复过程 2 直到队列为空,出队的顺序就是 BFS 结果

从 A 开始进行 DFS 的过程:

  1. 首先 从 A 开始走,其中一种情况:A->B->D->F
  2. 到 F 后没路走了,就会从上一个点重新走,所以回到 D->E->C
  3. 此时已经遍历完,所以 DFS 序列为:A B D F E C

DFS 的过程可用来描述:

  1. A 入栈,A 出栈, 然后与 A 相连的点入栈 C、B
  2. 栈顶 B 出栈,与栈顶 B 相连的点入栈 D
  3. 重复过程 2 直到栈为空,出栈顺序就是 DFS 结果

BFS 和 DFS 的实现

首先我们构建上面的图:

		public class BFSDemo {
		    public static void main(String[] args) {
		        //构造各顶点
		        LinkedList<Character> list_A = new LinkedList<Character>();
		        list_s.add('B');
		        list_s.add('C');
		        LinkedList<Character> list_B = new LinkedList<Character>();
		        list_w.add('A');
		        list_w.add('C');
		        list_w.add('D');
		        LinkedList<Character> list_C = new LinkedList<Character>();
		        list_r.add('A');
		        list_r.add('B');
		        list_r.add('D');
		        list_r.add('E');
		        LinkedList<Character> list_D = new LinkedList<Character>();
		        list_x.add('B');
		        list_x.add('C');
		        list_x.add('E');
		        list_x.add('F');
		        LinkedList<Character> list_E = new LinkedList<Character>();
		        list_v.add('C');
		        list_r.add('D');
		        LinkedList<Character> list_F = new LinkedList<Character>();
		        list_i.add('D');
		        
		        //构造图
		        HashMap<Character, LinkedList<Character>> graph = new HashMap<Character, LinkedList<Character>>();
		        graph.put('A', list_A);
		        graph.put('B', list_B);
		        graph.put('C', list_C);
		        graph.put('D', list_D);
		        graph.put('E', list_E);
		        graph.put('F', list_F);
		        //记录每个顶点离起始点的距离,也即最短距离
		        HashMap<Character, Integer> dist = new HashMap<Character, Integer>();
		        //遍历的起始点
		        char start = 'A';
		        //调用广度优先方法
		        bfs(graph, dist, start);
		        dfs(graph,dist,start);
		    }

BFS

		    public static void bfs(HashMap<Character, LinkedList<Character>> graph, HashMap<Character, Integer> dist,
		            char start) {
		        Queue<Character> q = new LinkedList<>();
		        q.add(start);// 将s作为起始顶点加入队列
		        dist.put(start, 0);
		        int i = 0;
		        while (!q.isEmpty()) {
		            char top = q.poll();// 取出队首元素
		            i++;
		            System.out.println("The " + i + "th element:" + top + " Distance from A is:" + dist.get(top));
		            int d = dist.get(top) + 1;// 得出其周边还未被访问的节点的距离
		            for (Character c : graph.get(top)) {
		                if (!dist.containsKey(c))// 如果dist中还没有该元素说明还没有被访问
		                {
		                    dist.put(c, d);
		                    q.add(c);
		                }
		            }
		        }
		    }
		}

结果如下:
在这里插入图片描述


DFS

		private static void dfs(HashMap<Character, LinkedList<Character>> graph, HashMap<Character, Integer> dist,
		            char start) {
		        Stack<Character> stack = new Stack<>();
		        stack.push(start);
		        dist.put(start, 0);
		        int i = 0;
		        while (!stack.isEmpty()) {
		            char top = stack.pop();// 取出栈顶元素
		            i++;
		            System.out.println("The " + i + "th element:" + top + " Distance from A is:" + dist.get(top));
		            int d = dist.get(top) + 1;
		            for (Character c : graph.get(top)) {
		                if (!dist.containsKey(c))
		                {
		                    dist.put(c, d);
		                    q.push(c);
		                }
		            }
		        }
		    }
		}

结果如下
3


BFS 和最短路径问题

1. 边不带权或权值都相同
定义一个map用来存放当前节点的parent节点

		HashMap<Character, Character> parent = new HashMap<Character, Character>();
		Character v = 'F';
		while(v!=null){//从 F 到 A 的最短路径       
		    System.out.println(v);
		    v = parent.get(v);    
		}        
		//bfs修改如下
		if (!dist.containsKey(c))
		{
			dist.put(c, d);
			parent.put(c,top);
		    q.push(c);
		}

结果如下:
4
2.边带不同权值的最短路径
使用优先级队列+ BFS 来实现 Dijkstra 算法

		  public static void main(String[] args) {                                          
		      //构造各顶点                                                                       
		      LinkedList<Node> list_A = new LinkedList<Node >();                            
		      list_A.add(new Node('B',5));                                                  
		      list_A.add(new Node('C',1));                                                  
		      LinkedList<Node> list_B = new LinkedList<Node>();                             
		      list_B.add(new Node('A',5));                                                  
		      list_B.add(new Node('C',2));                                                  
		      list_B.add(new Node('D',1));                                                  
		      LinkedList<Node> list_C = new LinkedList<Node>();                             
		      list_C.add(new Node('A',1));                                                  
		      list_C.add(new Node('B',2));                                                  
		      list_C.add(new Node('D',4));                                                  
		      list_C.add(new Node('E',8));                                                  
		      LinkedList<Node> list_D = new LinkedList<Node>();                             
		      list_D.add(new Node('B',1));                                                  
		      list_D.add(new Node('C',4));                                                  
		      list_D.add(new Node('E',3));                                                  
		      list_D.add(new Node('F',6));                                                  
		      LinkedList<Node> list_E = new LinkedList<Node>();                             
		      list_E.add(new Node('C',8));                                                  
		      list_E.add(new Node('D',3));                                                  
		      LinkedList<Node> list_F = new LinkedList<Node>();                             
		      list_F.add(new Node('D',6));                                                  
		                                                                                    
		      //构造图                                                                         
		      HashMap<Character, LinkedList<Node>> graph = new HashMap<Character, LinkedList
		      graph.put('A', list_A);                                                       
		      graph.put('B', list_B);                                                       
		      graph.put('C', list_C);                                                       
		      graph.put('D', list_D);                                                       
		      graph.put('E', list_E);                                                       
		      graph.put('F', list_F);                                                       
		      //记录每个顶点离起始点的距离,也即最短距离                                                        
		      HashMap<Character, Integer> dist = new HashMap<Character, Integer>();         
		      HashMap<Character, Character> parent = new HashMap<Character, Character>();   
		      ArrayList<Character> seen = new ArrayList<>();                                
		      
		      //初始化                                                                              
		      dist.put('A',0);                                                              
		      dist.put('B',Integer.MAX_VALUE);                                              
		      dist.put('C',Integer.MAX_VALUE);                                              
		      dist.put('D',Integer.MAX_VALUE);                                              
		      dist.put('E',Integer.MAX_VALUE);                                              
		      dist.put('F',Integer.MAX_VALUE);                                              
		                                                                                    
		      //遍历的起始点                                                                                                                               
		      Node start = new Node('A',0);                                                 
		      //调用广度优先方法                                                                    
		      bfs(graph,dist,seen,parent,start);                                                                                            
		      System.out.println(parent.toString());                                        
		      System.out.println(dist.toString());                                          
		                                                                                    
		  }
		  public static void bfs(HashMap<Character,LinkedList<Node>> graph,HashMap<Character, Integer> dist,ArrayList<Character> seen,HashMap<Character, Character> parent,Node start) {         
			    PriorityQueue<Node> q = new PriorityQueue<>(                                                            
			        new Comparator<Node>() {                                                                            
			            public int compare(Node o1, Node o2){                                                           
			                return o1.getNum()-o2.getNum();                                                             
			            }                                                                                               
			        });                                                                                                 
			    q.add(start);                                                                            
			    while (!q.isEmpty()) {                                                                                  
			        Node top = q.poll();                                                                                
			        char cr = top.getC();                                                                               
			        int dis = top.getNum();                                                                             
			        seen.add(cr);                                                                                       
			        for (Node c : graph.get(cr)) {                                                                      
			            if (!seen.contains(c.getC()))                                          
			            {                                                                                               
			                if(dis+c.getNum()<dist.get(c.getC())){                                                      
			                    q.add(c);                                                                               
			                    parent.put(c.getC(),cr);                                                                
			                    dist.put(c.getC(),dis+c.getNum());                                                      
			                    c.setNum(dis+c.getNum());//更新Node对象中的距离                                                               
			                }                                                                                           
			            }                                                                                               
			        }                                                                                                   
			    }                                                                                                       
			}                                                                                                                                                                                            

结果如下:
5

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值