zoukankan      html  css  js  c++  java
  • Java实现BFS广度优先查找

    1 问题描述
    广度优先查找(Breadth-first Search,BFS)按照一种同心圆的方式,首先访问所有和初始顶点邻接的顶点,然后是离它两条边的所有未访问顶点,以此类推,直到所有与初始顶点同在一个连通分量中的顶点都被访问过了为止。如果仍然存在未被访问的顶点,该算法必须从图的其他连接分量中的任意顶点重新开始。

    2 解决方案
    2.1 蛮力法

    此处借用《算法设计与分析基础》(第3版)上一段文字介绍及其配图来讲解,下面程序中使用的图就是配图中所给的数据,在程序中,使用邻接矩阵来表示配图中图。

    在这里插入图片描述

    在这里插入图片描述

    PS:下面所给程序的运行结果和配图中图(b)顺序在fb那两个位置不一致,下面程序运行结果顺序是acdebfghji,原因是在遍历的过程中,我所写代码是按照字母顺序来进行遍历的,书上所讲可能是使用链表来存储顶点,具体怎么实现本人也未去仔细探讨…

    package com.liuzhen.chapterThree;
    
    public class BreadthFirstSearch {
        public int count = 0;           //计算广度优先遍历总次数,初始化为0
         /*
         * adjMatrix是待遍历图的邻接矩阵
         * value是待遍历图顶点用于是否被遍历的判断依据,0代表未遍历,非0代表已被遍历,其最终具体结果代表该顶点在最终遍历顺序中的位置
         * result用于存放广度优先遍历的顶点顺序
         */
        public void bfs(int[][] adjMatrix,int[] value,char[] result){
            for(int i = 0;i < value.length;i++){
                if(value[i] == 0){                 //当该顶点未被遍历时
                    char temp = (char) ('a' + i);
                    result[count] = temp;
                    System.out.println();
                    System.out.println("出发点:"+temp+"地");
                    bfsVisit(adjMatrix,value,result,i);           //使用迭代遍历该顶点周边所有邻接顶点
                }
            }
        }
         /*
         * adjMatrix是待遍历图的邻接矩阵
         * value是待遍历图顶点用于是否被遍历的判断依据,0代表未遍历,非0代表已被遍历,其最终具体结果代表该顶点在最终遍历顺序中的位置
         * result用于存放广度优先遍历的顶点顺序
         * number是当前正在遍历的顶点在邻接矩阵中的数组下标编号
         */
        public void bfsVisit(int[][] adjMatrix,int[] value,char[] result,int number){
            value[number] = ++count;           //出发顶点已被遍历,其在遍历结果中最终位置为++count
            for(int i = 0;i < value.length;i++){
                if(adjMatrix[number][i] == 1 && value[i] == 0){         //当改顶点与出发顶点相邻且未被遍历时
                    char temp = (char) ('a' + i);
                    result[count] = temp;
                    System.out.print("到达"+temp+"地"+"	");
                    value[i] = ++count;                 //当前被遍历顶点,其在遍历结果中最终位置为++count
                }
            }
        }
        
        public static void main(String[] args){
            int[] value = new int[10];              //初始化后,各元素均为0
            char[] result = new char[10];
            char[] result1 = new char[10];
            int[][] adjMatrix = {{0,0,1,1,1,0,0,0,0,0},
                    {0,0,0,0,1,1,0,0,0,0},
                    {1,0,0,1,0,1,0,0,0,0},
                    {1,0,1,0,0,0,0,0,0,0},
                    {1,1,0,0,0,1,0,0,0,0},
                    {0,1,1,0,1,0,0,0,0,0},
                    {0,0,0,0,0,0,0,1,0,1},
                    {0,0,0,0,0,0,1,0,1,0},
                    {0,0,0,0,0,0,0,1,0,1},
                    {0,0,0,0,0,0,1,0,1,0}};
            BreadthFirstSearch test = new BreadthFirstSearch();
            test.bfs(adjMatrix, value, result);
            System.out.println();
            System.out.println("判断节点是否被遍历结果(0代表未遍历,非0代表已被遍历):");
            for(int i = 0;i < value.length;i++)
                System.out.print("  "+value[i]);
            //依据具体顶点在遍历结果顺序中最终位置,计算其具体遍历顺序为result1数组序列
            for(int i = 0;i < value.length;i++){
                result1[value[i]-1] = (char) ('a' + i);
            }
            System.out.println();
            System.out.println("判断节点是否被遍历结果(0代表未遍历,非0代表已被遍历,其具体数字代表其原地点在被遍历结果中所处位置:):");
            for(int i = 0;i < value.length;i++)
                System.out.print("  "+result1[i]);
            System.out.println();
            System.out.println("广度优先查找遍历顺序如下:");
            for(int i = 0;i < result.length;i++)
                System.out.print("  "+result[i]);
        }
    }
    

    运行结果:

    出发点:a地
    到达c地    到达d地    到达e地    
    出发点:b地
    到达f地    
    出发点:g地
    到达h地    到达j地    
    出发点:i地
    
    判断节点是否被遍历结果(0代表未遍历,非0代表已被遍历):
     5  2  3  4  6  7  8  10  9
    判断节点是否被遍历结果(0代表未遍历,非0代表已被遍历,其具体数字代表其原地点在被遍历结果中所处位置:):
      a  c  d  e  b  f  g  h  j  i
    广度优先查找遍历顺序如下:
      a  c  d  e  b  f  g  h  j  i
    
  • 相关阅读:
    c#中String跟string的“区别”<转>
    JS中判断对象是否为空
    report builder地址:http://localhost/reports
    今天开始,主攻MS Dynamics CRM
    IO负载高的来源定位
    ORACL学习笔记 之 分区表
    Linux自动删除n天前日志
    Oracle中NVL2 和NULLIF的用法
    Ubuntu学习笔记之Sqldeveloper安装
    给ubuntu的swap分区增加容量
  • 原文地址:https://www.cnblogs.com/a1439775520/p/12948078.html
Copyright © 2011-2022 走看看