zoukankan      html  css  js  c++  java
  • 无向图的广度优先遍历和深度优先遍历(简易实现)

    图的遍历就是从图中某个顶点出发,按某种方法对图中所有顶点访问且仅访问一次。
    图的遍历算法是求解图的连通性问题、拓扑排序和求关键路径等算法的基础,也可以用作网页的爬虫技术,
    深度优先遍历(depth-first search):类似于树的先根遍历,是树的先根遍历的推广,从一个图节点去访问它的邻接节点,
                     知道没有邻接节点后再回溯,然后继续向下访问(一般用栈的方式来实现)
    广度优先遍历(breadth-first search):遍历类似于树的层次遍历,它是树的按层遍历的推广(一般用队列的方式实现)
     
    在这个例子中,深度优先遍历是最右边的节点优先访问
     
      1 package graph;
      2 
      3 import java.util.Arrays;
      4 import java.util.HashMap;
      5 import java.util.LinkedList;
      6 import java.util.List;
      7 import java.util.Map;
      8 import java.util.Queue;
      9 import java.util.Stack;
     10 
     11 
     12 public class Graph {
     13     //声明一个map集合用来存放图的结构
     14     private Map<String, List<String>> graphMap=new HashMap<String, List<String>>();
     15     //建立无向图的模型
     16     //  图结构如下
     17     //         1
     18     //      /   
     19     //     2     3
     20     //    /    / 
     21     //    4  5  6  7
     22     //      | /  /
     23     //       8    9
     24     public void  initGraph() {
     25         /**
     26          * 初始化图结构,将每个图节点为key,它的相邻节点以list为value的形式存放到map中
     27          */
     28         graphMap.put("1",Arrays.asList("2","3"));
     29         graphMap.put("2",Arrays.asList("1","4","5"));
     30         graphMap.put("3",Arrays.asList("1","6","7"));
     31         graphMap.put("4",Arrays.asList("2","8"));
     32         graphMap.put("5",Arrays.asList("2","8"));
     33         graphMap.put("6",Arrays.asList("3","8","9"));
     34         graphMap.put("7",Arrays.asList("3","9"));
     35         graphMap.put("8",Arrays.asList("4","5","6"));
     36         graphMap.put("9",Arrays.asList("6","7"));
     37     }
     38     //用来记录节点是否被访问过
     39     private Map<String, Boolean> status=new HashMap<String,Boolean>();
     40     //创建一个队列用来进行宽度优先遍历
     41     private Queue<String> queue =new LinkedList<String>();
     42     public void BreadthFS(String startPoint) {
     43         //将图的起始点入队
     44         queue.offer(startPoint);
     45         status.put(startPoint, true);
     46         while(!queue.isEmpty()) {
     47             //将队首的元素出队
     48             String tempPoint =queue.poll();
     49             System.out.print(tempPoint+"-");
     50             //遍历之后的节点,将其状态改为false
     51             status.put(tempPoint, false);
     52             //遍历该节点邻接的节点
     53             for (String point : graphMap.get(tempPoint)) {
     54                 //如果该节点被访问过,则不入队
     55                 //getOrDefault:当集合中不存在该key,或者该key的值为null时则默认值为true
     56                 if(status.getOrDefault(point, true)){
     57                     //如果队列中已经存在了该节点,则不再次入队
     58                     if(!queue.contains(point)) {
     59                         queue.offer(point);
     60                     }
     61                 }
     62             }
     63         }
     64     }
     65     public void depthFS(String startPoint) {
     66         //建立一个栈用来进行深度优先遍历
     67         Stack<String> stack=new Stack<String>();
     68         //用来记录栈中元素的状态
     69         Map<String, Boolean> status=new HashMap<String,Boolean>();
     70         //将起始的点入栈
     71         stack.push(startPoint);
     72         while (!stack.isEmpty()) {
     73             //-----------显示栈内的数据情况----------------
     74             System.out.print("	");
     75                 for (String string : stack) {
     76                     System.out.print(string);
     77                     if(!string.equals(stack.lastElement())){
     78                         System.out.print("->");
     79                     }
     80                 }
     81                 System.out.println();
     82             //---------------------------
     83                 String tempPoint =stack.pop();//出栈
     84             
     85             //出栈后的元素标记为已遍历(false)
     86             status.put(tempPoint, false);
     87             //打印出栈顺序
     88             System.out.print(tempPoint);
     89             for (String point : graphMap.get(tempPoint)) {
     90                 //getOrDefault:当集合中不存在该key,或者该key的值为null时则默认值为true
     91                 if(status.getOrDefault(point, true)) {
     92                     //如果包含这个栈中没有这个元素-->入栈
     93                     //有这个元素,先删除栈中的该元素,再入栈。
     94                     if(!stack.contains(point)) {
     95                         stack.push(point);
     96                     }else {
     97                         stack.remove(point);
     98                         stack.push(point);
     99                     }
    100                 }
    101             }
    102         }
    103     }
    104     //用递归来实现无向图的深度优先遍历
    105     public void depthFSwithRecusive(String StartPoint) {
    106         if(status.getOrDefault(StartPoint,true)) {
    107             System.out.print(StartPoint+"-");
    108             status.put(StartPoint, false);
    109         }
    110         for (String point : graphMap.get(StartPoint)) {
    111             if(status.getOrDefault(point,true)) {
    112                 depthFSwithRecusive(point);
    113             }
    114         }
    115     }
    116 }

    测试代码:

     1 @org.junit.Test
     2     public void graphBFS() {
     3         Graph graph=new Graph();
     4         graph.initGraph();
     5         graph.BreadthFS("1");
     6     }
     7     @org.junit.Test
     8     public void graphDFS() {
     9         Graph graph=new Graph();
    10         graph.initGraph();
    11         graph.depthFS("1");
    12     }

    深度优先遍历的运行结果:(最左边为 出栈顺序,右边是栈内信息的打印)

    深度优先遍历的运行结果:

  • 相关阅读:
    Atitit.eclise的ide特性abt 编译
    Atitit python3.0 3.3 3.5 3.6 新特性 Python2.7新特性1Python 3_x 新特性1python3.4新特性1python3.5新特性1值得关注的新特性1Pyth
    Atitit. Atiposter 发帖机 新特性 poster new feature   v7 q39
    Atitit.eclipse 4.3 4.4  4.5 4.6新特性
    atitit.错误:找不到或无法加载主类 的解决 v4 qa15.doc
    Atitit RSA非对称加密原理与解决方案
    Atitti.数字证书体系cer pfx attilax总结
    Atitit ftp原理与解决方案
    Atitit qzone qq空间博客自动点赞与评论工具的设计与实现
    Atitit 软件国际化原理与概论
  • 原文地址:https://www.cnblogs.com/Not-Leave-Regrets/p/11676061.html
Copyright © 2011-2022 走看看