小言_互联网的博客

广度优先搜索BFS

465人阅读  评论(0)

广度优先搜索是图里面一种基础的搜索算法,英文简写BFS(breadth First Search),广度优先搜索能够搜索到源节点S到图中其他节点的最短距离,该方法适用于无权有向或者无权无向图中,

 

广度优先搜索采用的方式类似二叉树的层次遍历,比如对节点V3来说,V1、V5属于第一层,V4、V6、V2属于第二层,从V3到V5的最短距离是V3->V5这条边,而不是从V3->V1->V4->V5,好比人类关系一样,比如A、B、C、D、E五人,A认识B,B认识C,C认识E,于此同时A认识D,D也认识E,比如A需要找E办点事,正常的逻辑是通过D结实E,这样只需经过两道关系,通过B的话则需要经过三道关系,广度优先搜索类似,按照距离源节点的远近来进行检索。

下面给出广度优先搜索的java实现:


  
  1. /**
  2. **图的节点类
  3. **/
  4. public class Vertex {
  5. //该节点颜色,当color为VertexColor.WHITE时表名该节点没有被路由过,为其他颜色说明已经被使用过,后续路径的遍历就不要再遍历这个节点了,前面已经提到了广度优先搜索的层次搜索概念,最先被搜索到的是与源节点关系最近的路径
  6. private VertexColor color;
  7. //源节点到该顶点的距离
  8. private int distance;
  9. //前驱节点
  10. private Vertex pre;
  11. //该顶点的连接队列
  12. private List<Vertex> adjList;
  13. //统计该节点在图顶点数组下标,对广度搜索非必要属性,仅用于统计使用
  14. private int index ;
  15. public Vertex(int index){
  16. this.index = index;
  17. adjList = new LinkedList<>();
  18. this.color = VertexColor.WHITE;
  19. this.pre = null;
  20. this.distance = Integer.MAX_VALUE;
  21. }
  22. //添加邻接矩阵点
  23. public void addVertex(Vertex v){
  24. this.adjList. add(v);
  25. }
  26. public VertexColor getColor() {
  27. return color;
  28. }
  29. public void setColor(VertexColor color) {
  30. this.color = color;
  31. }
  32. public int getDistance() {
  33. return distance;
  34. }
  35. public void setDistance(int distance) {
  36. this.distance = distance;
  37. }
  38. public Vertex getPre() {
  39. return pre;
  40. }
  41. public void setPre(Vertex pre) {
  42. this.pre = pre;
  43. }
  44. public List<Vertex> getAdjList() {
  45. return adjList;
  46. }
  47. public void setAdjList(List<Vertex> adjList) {
  48. this.adjList = adjList;
  49. }
  50. @ Override
  51. public String toString( ){
  52. return String.format( "到节点:%d的最短距离为:%d,前驱节点下标为:%d,当前颜色为:%s", index,distance,pre.index,color);
  53. }
  54. }

  
  1. //顶点颜色
  2. public enum VertexColor {
  3. WHITE, GRAY, BLACK;
  4. }

  
  1. public class Graph {
  2. //图中的顶点
  3. private List<Vertex> vertexes;
  4. public Graph(int len){
  5. //初始化时指定长度,避免扩容
  6. vertexes = new ArrayList<>(len);
  7. }
  8. public void addVertex(Vertex v){
  9. vertexes. add(v);
  10. }
  11. public List<Vertex> getVertexes() {
  12. return vertexes;
  13. }
  14. public void setVertexes(List<Vertex> vertexes) {
  15. this.vertexes = vertexes;
  16. }
  17. }

上面为基础类,下面为demo代码:


  
  1. @ Test
  2. public void bfsSearch( ){
  3. Graph g= new Graph( 6);
  4. Vertex v1 = new Vertex( 1);
  5. Vertex v2 = new Vertex( 2);
  6. Vertex v3 = new Vertex( 3);
  7. Vertex v4 = new Vertex( 4);
  8. Vertex v5 = new Vertex( 5);
  9. Vertex v6 = new Vertex( 6);
  10. //初始化图的顶点数组
  11. g.addVertex(v1);
  12. g.addVertex(v2);
  13. g.addVertex(v3);
  14. g.addVertex(v4);
  15. g.addVertex(v5);
  16. g.addVertex(v6);
  17. //初始化邻接矩阵
  18. v1.addVertex(v2);
  19. v1.addVertex(v4);
  20. //
  21. v2.addVertex(v4);
  22. //
  23. v3.addVertex(v1);
  24. v3.addVertex(v5);
  25. //
  26. v4.addVertex(v5);
  27. v4.addVertex(v6);
  28. //
  29. v5.addVertex(v6);
  30. //查找v3节点到其他节点的最短距离
  31. println( "节点v3到其他节点的最短距离");
  32. bfs(g,v3);
  33. //查找v1节点到其他节点的最短距离
  34. println( "节点v1到其他节点的最短距离");
  35. bfs(g,v1);
  36. }
  37. public void bfs(Graph g,Vertex s){
  38. //清空数据
  39. List<Vertex> vertexList = g.getVertexes();
  40. for(Vertex v:vertexList){
  41. v.setColor(VertexColor.WHITE);
  42. v.setDistance(Integer.MAX_VALUE);
  43. v.setPre( null);
  44. }
  45. //设置源节点数据,自己到自己的最短距离为0
  46. s.setDistance( 0);
  47. s.setColor(VertexColor.GRAY);
  48. //LinkedList也是一种队列
  49. Queue<Vertex> q = new LinkedList<>();
  50. q. add(s);
  51. while(!q.isEmpty()){
  52. //将顶点从队列弹出
  53. Vertex u = q. remove();
  54. List<Vertex> list = u.getAdjList();
  55. for(Vertex v:list){
  56. if(v.getColor() == VertexColor.WHITE){
  57. v.setColor(VertexColor.GRAY);
  58. //设置源节点到该节点的距离,在前驱节点的基础上加1
  59. v.setDistance(u.getDistance()+ 1);
  60. //
  61. v.setPre(u);
  62. //将v入队列
  63. q. add(v);
  64. }
  65. }
  66. //更新u节点颜色
  67. u.setColor(VertexColor.BLACK);
  68. }
  69. //输出源节点到每个节点的最短距离
  70. for(Vertex v:vertexList){
  71. if(v == s || v.getDistance() == Integer.MAX_VALUE)
  72. continue;
  73. println(v.toString());
  74. }
  75. }

输出:
节点v3到其他节点的最短距离
到节点:1的最短距离为:1,前驱节点下标为:3,当前颜色为:BLACK
到节点:2的最短距离为:2,前驱节点下标为:1,当前颜色为:BLACK
到节点:4的最短距离为:2,前驱节点下标为:1,当前颜色为:BLACK
到节点:5的最短距离为:1,前驱节点下标为:3,当前颜色为:BLACK
到节点:6的最短距离为:2,前驱节点下标为:5,当前颜色为:BLACK
节点v1到其他节点的最短距离
到节点:2的最短距离为:1,前驱节点下标为:1,当前颜色为:BLACK
到节点:4的最短距离为:1,前驱节点下标为:1,当前颜色为:BLACK
到节点:5的最短距离为:2,前驱节点下标为:4,当前颜色为:BLACK
到节点:6的最短距离为:2,前驱节点下标为:4,当前颜色为:BLACK


转载:https://blog.csdn.net/john1337/article/details/104464086
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场