换人!小编连怎么能快速找到女朋友都不知道

简介: 换人!小编连怎么能快速找到女朋友都不知道

换人!小编连怎么能快速找到女朋友都不知道

在数据结构中对广撒网有一种类似的定义,叫做广度优先搜索(Breadth-First-Search),简称BFS。是一种“地毯式”层层推进的搜索策略,即先查找离起始顶点最近的,然后是次进的,依次往外搜索。

image.png


先把一个顶点附近的顶点查找一遍,然后再从它附近的顶点开始查找,重复一样的操作。如上图所示,先从A点出发,查找离A点最近的B和C,如果这两个不是想要的节点,那么就以B和C为起点,查找与B和C相连接的顶点。广度优先搜索策略得到的路径是起始点到终点的最短路径


为什么说广度优先搜索策略找到的路径是最短路径呢?最简单的一种解释方式,想想圆规画圆,以A点为顶点,不断的增加圆的半径。


这个像不像你先跟某寝室的女孩子小A相处,然后发现小A不跟你玩,然后你开始通过A对她的室友下手,emmm……最后得出结论,渣男实锤了。我们下次还是聊点专一的操作吧。


编程逻辑

  1. 从一个顶点 A 出发,查找与 A 相通的其它顶点
  2. 判断查找的顶点是否访问过,访问过则直接跳过
  3. 如果顶点没有访问过,判断顶点是否为要查找的顶点
  4. 如果是不是要查找到顶点,则标记顶点为已访问的状态
  5. 把刚刚更改状态的顶点放入待查找顶点集合
  6. 接着寻找顶点 A 的相通顶点,重复 2 ~ 5 的步骤
  7. 当 A 的通顶点都遍历一遍时,从待查找顶点集合中取出一个元素,重复上述 1 ~ 6 的操作

代码实现

import java.util.LinkedList;
import java.util.Queue;
/**
 * 广度优先搜索
 *
 * @since 2021-03-18
 */
public class GrapBfs {
    // 顶点的个数
    private int v;
    // 邻接表
    private LinkedList<Integer>[] adj;
    public GrapBfs(int v) {
        this.v = v;
        adj = new LinkedList[v];
        for (int i = 0; i < v; i++) {
            adj[i] = new LinkedList<>();
        }
        visited = new boolean[v];
        pre = new Integer[v];
        for (int i = 0; i < v; i++) {
            pre[i] = -1;
        }
    }
    /**
     * 一条边的两个顶点,表示两个边相连
     *
     * @param s 顶点
     * @param t 顶点
     */
    public void addEdge(int s, int t) {
        adj[s].add(t);
        adj[t].add(s);
    }
    public int getV() {
        return v;
    }
    public LinkedList<Integer>[] getAdj() {
        return adj;
    }
    // 存放接下来需要查找其周边顶点的顶点
    Queue<Integer> queue = new LinkedList<>();
    // 记录顶点是否已经被访问过
    boolean[] visited;
    // 记录顶点的前一个顶点
    Integer[] pre;
    /**
     * 广度优先搜索
     * 
     * @param start 起始位置
     * @param end 结束位置
     */
    public void bfs(int start, int end) {
        if (start == end) {
            return;
        }
        queue.offer(start);
        Integer present;
        visited[start] = true;
        while (!queue.isEmpty()) {
            present = queue.poll();
            LinkedList<Integer> linkedList = adj[present];
            for (Integer nextVertex : linkedList) {
                if (visited[nextVertex]) {
                    continue;
                }
                visited[nextVertex] = true;
                pre[nextVertex] = present;
                if (nextVertex == end) {
                    print(pre, nextVertex);
                    System.out.println(end);
                    return;
                }
                queue.offer(nextVertex);
            }
        }
    }
    /**
     * 输出查找的路径
     * 
     * @param pre 记录顶点前一个顶点的数组
     * @param nextVertex 当前顶点的下一个顶点
     */
    private void print(Integer[] pre, Integer nextVertex) {
        if (pre[nextVertex] == -1) {
            return;
        }
        print(pre, pre[nextVertex]);
        System.out.print(pre[nextVertex]);
    }
    public static void main(String[] args) {
        GrapBfs grap = new GrapBfs(9);
        grap.addEdge(1, 2);
        grap.addEdge(1, 4);
        grap.addEdge(2, 3);
        grap.addEdge(2, 5);
        grap.addEdge(3, 6);
        grap.addEdge(4, 5);
        grap.addEdge(5, 6);
        grap.addEdge(5, 7);
        grap.addEdge(6, 8);
        grap.addEdge(7, 8);
        grap.bfs(1, 7);
    }
}

复杂度

V 表示顶点的个数,E 表示边的个数

广度优先搜索的时间复杂度为O(E),空间复杂度为O(V)

最坏的情况下,我们从一个顶点出发,需要遍历整个图才能找到需要查找的顶点,此时每个顶点都要进出遍集合,每个边被访问一边,所以时间复杂度为O(V+E)

对一个连通图来说,也就是一个图中的所有顶点都是连通的,E 肯定要大于等于 V-1,所以时间复杂度简写为O(E)

空间消耗主要有是待访问顶点的集合,标记已访问的集合。每一块需要的口存储空间大小都不会超过顶点的个数,所以空间复杂度为O(V)

目录
相关文章
|
存储 数据安全/隐私保护 开发者
开发搭建体育赛事直播平台详细的步骤和建议
开发创建体育赛事直播平台是一个备受欢迎的创业选择,尤其在体育赛事在线观看和直播技术不断提升的情况下。下面是详细的步骤和建议,以确保您的项目成功上线并满足用户需求。
|
测试技术 开发工具 C++
【软件设计师备考 专题 】软件开发环境和工具
【软件设计师备考 专题 】软件开发环境和工具
474 0
|
4月前
|
安全 前端开发 Java
Spring Security
Spring Security 是Java应用安全的基石,提供认证、授权等全方位防护。支持表单、OAuth2、JWT等多种认证方式,基于过滤器链实现精细控制,适配单体、前后端分离及微服务架构,是构建企业级安全体系的首选框架。
|
10月前
|
人工智能 自然语言处理 搜索推荐
创作者会被AI取代吗?AIGC为电影行业带来新变革
在AI技术飞速发展的今天,AIGC(AI生成内容)正深刻改变电影行业的内容生成、制作流程与商业模式。创作者角色从执行者向策划者转变,需与AI协作挖掘创意与情感价值。生成式人工智能认证(GAI认证)成为新时代创作者必备资质,助力其在人机共生的新生态中保持竞争力,共同推动创作领域迈向更高层次。拥抱变革,共创未来,是每个创作者在AI时代的必由之路。
创作者会被AI取代吗?AIGC为电影行业带来新变革
|
机器学习/深度学习 人工智能 自然语言处理
CogAgent-9B:智谱 AI 开源 GLM-PC 的基座模型,专注于预测和执行 GUI 操作,可应用于自动化交互任务
CogAgent-9B 是智谱AI基于 GLM-4V-9B 训练的专用Agent任务模型,支持高分辨率图像处理和双语交互,能够预测并执行GUI操作,广泛应用于自动化任务。
423 12
CogAgent-9B:智谱 AI 开源 GLM-PC 的基座模型,专注于预测和执行 GUI 操作,可应用于自动化交互任务
|
人工智能 搜索推荐 iOS开发
OpenAI推出适用于iPhone的ChatGPT,与Apple实现具有里程碑意义的AI整合
OpenAI推出适用于iPhone的ChatGPT,与Apple实现具有里程碑意义的AI整合
|
应用服务中间件 Linux nginx
“直播”极简教程
本文以一个非常简单的实际例子,搭建一个直播所需要的基础软件支撑平台,浅尝直播业务中核心业务概念及他们的交互流程。 对于一场直播,大致会拥有如下环节: * 主播通过直播设备将画面推送到直播平台 * 平台接收主播推送的画面 * 观众通过平台找到主播的直播画面,具体来说就是要找到主播的房间号 * 观众从平台拉取房间号中的直播画面
570 10
“直播”极简教程
|
XML 数据可视化 C语言
001 Qt_从零开始创建项目
本文是Qt专栏的第一篇,介绍了如何创建一个Qt项目。
448 4
|
存储
串行口通信原理及操作流程
串行口通信是一种将数据以串行方式传输的通信方式,它通过一根传输线(串行线)将数据位逐位地传输,相比并行通信,串行通信可以减少传输线的数量,提高传输效率。以下是串行口通信的原理及操作流程的详细介绍。 1. 原理: 串行口通信使用串行通信协议进行数据传输。常见的串行通信协议包括RS-232、RS-485、UART等。这些协议规定了数据传输的格式、波特率、起始位、停止位、校验位等参数。 在串行口通信中,数据被分割成多个数据位,每个数据位逐个传输。数据位之间通过特定的时钟信号进行同步。发送端将数据位按照协议规定的格式发送到传输线上,接收端通过解析接收到的数据位来恢复原始数据。通过这种方式,数据可以
693 0
|
Java BI 测试技术
【Docker项目实战】使用Docker部署SurveyKing调查问卷系统和考试系统
【8月更文挑战第5天】使用Docker部署SurveyKing调查问卷系统和考试系统
585 2