算法—图算法—广度优先搜索

545 阅读1分钟

图算法

一、广度优先搜索算法

解决问题:

  1. 我能到那个节点吗?
  2. 到那个节点的最少步骤?

理论步骤:

将出发点的邻接节点加入搜索队列中,弹出一个邻接节点做:

  1. 如果是终点,直接返回
  2. 如果不是,将它的邻接节点加入待搜索队列中(加入的节点必须是没访问过的)
  3. 重复以上过程

例如:从你开始,在你的关系网中,找到一个关系距离你最近的芒果销售商,返回该销售商

关系图:

image-20210129164219392

步骤:

image-20210129164328142

代码实现:

关系:

image-20210129172151219

代码:

package 算法.广度优先搜索算法;

import java.util.ArrayDeque;
import java.util.HashSet;
import java.util.Set;

public class Solution {
    //图的每一个节点
    static class Person{
        public String name;
        public Boolean flag;//是否是销售商
        public Set<Person> relationShips = new HashSet<>();//有关系的人
        public Person(String name, Boolean flag) {
            this.name = name;
            this.flag = flag;
        }
    }
    
    
    public static void main(String[] args) {
        //you 是你自己,bcdef是你的关系网
        Person you = new Person("A", false);
        Person b = new Person("B", false);
        Person c = new Person("C", false);
        Person d = new Person("D", false);
        Person e = new Person("E", true);
        Person f = new Person("F", true);
        
        //定义关系
        you.relationShips.add(b);
        you.relationShips.add(c);
        b.relationShips.add(e);
        c.relationShips.add(d);
        d.relationShips.add(e);
        d.relationShips.add(f);

        //广度搜索优先算法
        //从你开始,找到你关系网中最近的芒果销售商
        Person person = breadthFirstSearch(you);
        System.out.println("距离你最近的销售商为"+person.name);
    }
    
    //广度优先搜索
    public static Person breadthFirstSearch(Person start){
        ArrayDeque<Person> searchQueue = new ArrayDeque<>();//搜索队列
        //将you的关系网加入搜索队列中
        searchQueue.addAll(start.relationShips);

        //被搜索过的人可以加入到该集合中,可以被排除
        HashSet<Person> searched = new HashSet<>();

        //如果搜索队列不为空,循环遍历
        while (!searchQueue.isEmpty()){
            Person peek = searchQueue.poll();
            if (!searched.contains(peek)){
                //如果没有被访问过(没有在searched中),并且是销售商,直接返回
                if (peek.flag){
                    return peek;
                }
                //不是销售商,把它的关系网加入到搜索队列中
                searchQueue.addAll(peek.relationShips);
                //标记为访问过
                searched.add(peek);
            }
        }
        return null;
    }
}