【软考】图的遍历

目录

        • 1. 概念
        • 2. 深度优先搜索
          • 2.1 说明
          • 2.2 步骤
        • 3. 深度优先搜索例子
          • 3.1 无向图
          • 3.2 代码示例
          • 3.3 结果示例
          • 3.4 过程
        • 4. 广度优先搜索
          • 4.1 说明
          • 4.2 步骤
        • 5. 广度优先搜索例子
          • 5.1 无向图
          • 5.2 代码示例
          • 5.3 结果示例
          • 5.4 过程
          • 5.5 例题
            • 5.5.1 题目1

1. 概念
  • 1.图的遍历是指从某个顶点出发,沿着某条搜索路径对图中的所有顶点进行访问且只访问一次的过程
  • 2.图的遍历算法是求解图的连通性问题、拓扑排序及求关键路径等算法的基础
  • 3.图的遍历比树的遍历复杂
  • 4.图的任一个结点都可能与其余顶点相邻接,所以在访问了某个顶点之后,可能沿着某路径又回到该结点上,为了避免对顶点进行重复访问,在图的遍历过程中必须记下每个已访问过的顶点
  • 5.深度优先搜索和广度优先搜索是两种遍历图的基本方法
2. 深度优先搜索
2.1 说明
  • 1.Depth First Search, DFS
  • 2.类似于树的先根比遍历,在第一次经过一个顶点时就进行访问访问操作
  • 3.深度优先遍历图的过程实质上是对某个顶点查找其邻接点的过程,其耗费的时间取决于所采用的存储结构
  • 4.当图用邻接矩阵表示时,查找所有顶点的邻接点所需时间为 O(n)。
  • 5.若以邻接表作为图的存储结构,则需要 O(e)的时间复杂度查找所有顶点的邻接点。因此,当以邻接表作为存储结构时,深度优先搜索遍历图的时间复杂度为 O(n+e)。
2.2 步骤
  • 1.设置搜索指针p,使p指向顶点v
  • 2.访问p所指顶点,并使p指向与其相邻接的且尚未被访问过的顶点
  • 3.若p所指顶点存在,则重复步骤2,否则执行步骤4
  • 4.沿着刚才访问的次序和方向回溯到一个尚有邻接顶点且未被访问过的顶点,并使p指向这个未被访问的顶点,然后重复步骤2,直到所有的顶点均被访问为止
  • 5.该算法的特点是尽可能先对纵深方向搜索,因此可以得到其递归遍历算法
  • 6.
3. 深度优先搜索例子
3.1 无向图
3.2 代码示例
package com.learning.algorithm.search.graph;

import java.util.*;

public class Graph {
    // 顶点的数量
    private int number;
    // 邻接列表
    private LinkedList<Integer>[] adjacency;

    public Graph(int number) {
        this.number = number;
        adjacency = new LinkedList[number];
        for (int i = 0; i< number; ++i) {
            adjacency[i] = new LinkedList();
        }
    }

    // 向图中添加边
    public void addEdge(int v, int w) {
        adjacency[v].add(w);
    }

    // 从v可达顶点的深度优先搜索
    public void depthFirstSearch(int v, boolean visited[]) {
        // 将当前节点标记为已访问并打印
        visited[v] = true;
        System.out.print(v+" ");

        // 对与此顶点相邻的所有顶点重复搜索
        Iterator<Integer> i = adjacency[v].listIterator();
        while (i.hasNext()) {
            int n = i.next();
            if (!visited[n]) {
                depthFirstSearch(n, visited);
            }
        }
    }

    public static void main(String args[]) {
        Graph g = new Graph(4);

        g.addEdge(0, 1);
        g.addEdge(0, 2);
        g.addEdge(1, 2);
        g.addEdge(2, 0);
        g.addEdge(2, 3);
        g.addEdge(3, 3);

        // 从顶点2开始
        boolean[] visited = new boolean[g.number];
        g.depthFirstSearch(2, visited);
    }
}
3.3 结果示例

在这里插入图片描述

3.4 过程
  • 1.从顶点2开始搜索,将顶点2标记为已访问
  • 2.获取顶点2可到达的顶点0和顶点3
  • 3.判断顶点0是否已访问,没有访问,则从顶点0开始搜索,将顶点0标记为已访问(从第2点过来的)
  • 4.获取顶点0可到达的顶点1和顶点2(从第3点过来的)
  • 5.判断顶点1是否已访问,没有访问,则从顶点1开始搜索,将顶点1标记为已访问(从第4点过来的)
  • 6.获取顶点1可到达的顶点0和顶点2(从第5点过来的)
  • 7.判断顶点0是否已访问,顶点0已访问(从第6点过来的)
  • 8.判断顶点2是否已访问,顶点2已访问(从第6点过来的)
  • 9.判断顶点2是否已访问,顶点2已访问(从第4点过来的)
  • 10.判断顶点3是否已访问,没有访问,则从顶点3开始搜索,将顶点3标记为已访问(从第2点过来的)
  • 11.获取顶点3可到达的顶点2和顶点3(从第10点过来的)
  • 12.判断顶点2是否已访问,顶点2已访问(从第11点过来的)
  • 13.判断顶点3是否已访问,顶点3已访问(从第11点过来的)
4. 广度优先搜索
4.1 说明
  • 1.Breadth First Search, BFS
  • 2.广度优先遍历图的特点是尽可能先进行横向搜索,即最先访问的顶点的邻接点也先被访问。为此引入队列来保存已访问过的顶点序列,即每当一个顶点被访问后,就将其放入队列中,当队头顶点出队时,就访问其未被访问的邻接点并令这些邻接顶点入队
  • 3.在广度优先遍历算法中,每个顶点最多尽进一次队列
  • 4.遍历图的过程实质上是通过边或弧找邻接点的过程,因此广度优先搜索遍历图和深度优先搜索遍历图的运算时间复杂度相同,其不同之处仅仅在于对顶点访问的次序不同
4.2 步骤
  • 1.图的广度优先搜索方法为:从图中的某个顶点v出发,在访问了v之后依次访问v的各个未被访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问,直到图中所有已被访问的顶点的邻接点都被访问到。若此时还有未被访问的点,则另选图中的一个未被访问的顶点作为起点,重复上述过程,直到图中所有的顶点都被访问到为止
5. 广度优先搜索例子
5.1 无向图
5.2 代码示例
package com.learning.algorithm.search.graph.breadth_first_search;

import java.util.*;
  
public class Graph {
    private int number;
    private LinkedList<Integer>[] adjacency;
  
    public Graph(int number) {
        this.number = number;
        adjacency = new LinkedList[number];
        for (int i = 0; i < number; ++i) {
            adjacency[i] = new LinkedList();
        }
    }

    public void addEdge(int src, int dest) {
        adjacency[src].add(dest);
        // 因为是无向图,所以需要添加反向边
        adjacency[dest].add(src);
    }

    public void breadthFirstSearch(int v) {
        boolean visited[] = new boolean[number];
        Queue<Integer> queue = new LinkedList<>();

        visited[v] = true;
        queue.add(v);

        while (!queue.isEmpty()) {
            int currentVertex = queue.poll();
            System.out.print(currentVertex + " "); // 访问当前节点

            Iterator<Integer> i = adjacency[currentVertex].listIterator();
            while (i.hasNext()) {
                int adjacentVertex = i.next();
                if (!visited[adjacentVertex]) {
                    visited[adjacentVertex] = true;
                    queue.add(adjacentVertex);
                }
            }
        }
    }
  
    public static void main(String args[]) {  
        Graph g = new Graph(7);

        g.addEdge(0, 1);
        g.addEdge(0, 4);
        g.addEdge(1, 2);
        g.addEdge(1, 3);
        g.addEdge(1, 4);
        g.addEdge(2, 3);
        g.addEdge(3, 4);

        g.breadthFirstSearch(0);
    }
}
5.3 结果示例

在这里插入图片描述

5.4 过程
  • 1.从图中的顶点0出发,将顶点0标记为已访问,将顶点0放入队列
  • 2.如果队列不为空,拿出队首顶点0,打印顶点0,获取顶点0可到达的顶点,即顶点1和顶点4
  • 3.顶点1没有被访问,将顶点1标记为已访问,将顶点1放入队列
  • 4.顶点4没有被访问,将顶点4标记为已访问,将顶点4放入队列
  • 5.此时队列不为空,拿出队首顶点1,打印顶点1,获取顶点1可到达的顶点,即顶点0,顶点2,顶点3和顶点4
  • 6.顶点0已经被访问
  • 7.顶点2没有被访问,将顶点2标记为已访问,将顶点2放入队列
  • 8.顶点3没有被访问,将顶点3标记为已访问,将顶点3放入队列
  • 9.顶点4已经被访问
  • 10.此时队列不为空,拿出队首顶点4,打印顶点4,获取顶点4可到达的顶点,即顶点0,顶点1和顶点3
  • 11.顶点0已经被访问
  • 12.顶点1已经被访问
  • 13.顶点3已经被访问
  • 14.此时队列不为空,拿出队首顶点2,打印顶点2,获取顶点2可到达的顶点,即顶点1和顶点3
  • 15.顶点1已经被访问
  • 16.顶点3已经被访问
  • 15.此时队列不为空,拿出队首顶点3,打印顶点3,获取顶点3可到达的顶点,即顶点1,顶点2和顶点4
  • 16.顶点1已经被访问
  • 17.顶点2已经被访问
  • 18.顶点4已经被访问
  • 19.此时队列为空结束

从图中的某个顶点v出发,在访问了v之后依次访问v的各个未被访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问,直到图中所有已被访问的顶点的邻接点都被访问到。若此时还有未被访问的点,则另选图中的一个未被访问的顶点作为起点,重复上述过程,直到图中所有的顶点都被访问到为止

5.5 例题
5.5.1 题目1
  • 1.题目内容
例题1:图G的邻接矩阵如下图所示(顶点依次表示为v0、v1、v2、v3、v4、v5),G是( 1 )。
对G进行广度优先遍历(从v0开始),可能的遍历序列为( 2 )。
1. 	A.无向图 B.有向图 C.完全图 D.强连通图

2. 	A.v0、v1、v2、v3、v4、v5
	B.v0、v2、v4、v5、v1、v3
	C.v0、v1、v3、v5、v2、v4
	D.v0、v2、v4、v3、v5、v1
  • 2.题目解析
1.由图可以看出,v0可以到达v1和v2,v1可以到达v3,v2可以到达v1和v3,v3可以到达v5,v4可以到达v5
2.部分是单向的因此不是无向图,而是有向图,选B
3.不是完全图(完全图是一个简单的无向图,其中每对不同的顶点之间都恰有一条边相连)
4.不是强连通图(任意两个顶点之间都存在至少一条从一个顶点到另一个顶点的路径,同时也存在至少一条反向的路径)

5.v0可以到v1和v2,则v0、v1、v2,因此选A

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/445931.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Day32-计算机基础2

Day32-计算机基础2 1. 什么是网络拓扑(Network Topology)&#xff1f;2. 网络拓扑3种经典模型2.1 网络拓扑结构-总线型2.2 网络拓扑结构-环形2.3 星型&#xff1a;2.4 网络拓扑结构总结 3.OSI网络模型概念*****3.1 OSI的概念&#xff1a;open system interconnect 开放系统互连…

第五十三天| 1143.最长公共子序列、1035.不相交的线、53. 最大子序和

Leetcode 1143.最长公共子序列 题目链接&#xff1a;1143 最长公共子序列 题干&#xff1a;给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&…

CentOS7部署SonarQube 9.9.4 LTS

文章目录 下载地址前置条件安装sonarqube创建用户解压修改sonar.properties配置文件 启动sonarqube开启防火墙端口启动报错访问SonarQube安装汉化包 安装sonar-scanner 下载地址 社区稳定版本 版本依赖关系 Prerequisites and overview (sonarsource.com) 前置条件 JDK11安…

vscode插件-TONGYILingma

通义灵码&#xff0c;是一款基于通义大模型的智能编码辅助工具&#xff0c;提供行级/函数级实时续写、自然语言生成代码、单元测试生成、代码注释生成、代码解释、研发智能问答、异常报错排查等能力&#xff0c;并针对阿里云 SDK/API 的使用场景调优&#xff0c;为开发者带来高…

js之原型链

在JavaScript中&#xff0c;原型链是一种用于实现继承和属性查找的机制。每个对象都有一个内部属性[[Prototype]]&#xff0c;这个属性指向创建该对象时使用的构造函数的“prototype"属性。对象的方法和属性定义在它的原型对象上。 1.原型&#xff08;Prototypes&#xf…

Kafka 面试题及答案整理,最新面试题

Kafka中的Producer API是如何工作的&#xff1f; Kafka中的Producer API允许应用程序发布一流的数据到一个或多个Kafka主题。它的工作原理包括&#xff1a; 1、创建Producer实例&#xff1a; 通过配置Producer的各种属性&#xff08;如服务器地址、序列化方式等&#xff09;来…

SQL 注入攻击 - delete注入

环境准备:构建完善的安全渗透测试环境:推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 一、注入原理: 对于后台来说,delete操作通常是将对应的id传递到后台,然后后台会删除该id对应的数据。 如果后台没有对接收到的 id 参数进行充分的验证和过滤,恶意用户可能会…

基于Vue的娱讯移动端APP前端设计与实现

目 录 摘 要 Abstract 引 言 1绪论 1.1课题背景及目的 1.1.1移动端APP发展简介 3 1.1.2移动端APP的优势 3 1.2前端开发相关技术 1.2.1前端开发工具介绍 3 1.2.2 前端开发相关技术介绍 4 1.3本章小结 2系统分析 2.1功能需求分析 2.2系统工作流程 2.3本章小结 3系统设…

Breach-2.1

靶场环境说明 该靶场是静态IP地址&#xff0c;需要更改网络配置&#xff0c;攻击机kali做了两张网卡&#xff1b; 信息收集 # nmap -sT --min-rate 10000 -p- 192.168.110.151 -oN port.nmap Starting Nmap 7.94 ( https://nmap.org ) at 2024-02-09 10:47 CST Stats: 0:00:…

2022年我国茶树分布数据以及数据制作过程详细介绍

茶树&#xff08;Camellia sinensis&#xff09;是一种典型的农林作物&#xff0c;在60多个国家种植&#xff0c;作为一种重要的特色经济作物&#xff0c;具有重要的经济和社会意义。准确的全国作物数据对于有效的农业管理和资源监管至关重要。然而&#xff0c;许多区域都在努力…

利用Amazon Bedrock畅玩Claude 3等多种领先模型,抢占AI高地(体验倒计时4小时)

快乐的时间总是短暂的&#xff0c;Claude 3 在亚马逊云科技上限时体验仅剩4小时&#xff0c;上次分享了入门级操作教程&#xff0c;本期给大家带来AWS Lambda Amazon Bedrock一起构建可以便捷使用的Claude 3接口 AWS Lambda AWS Lambda 是一项计算服务&#xff0c;可以运行您…

JZ76 删除链表中重复的结点

/*public class ListNode {int val;ListNode next null;ListNode(int val) {this.val val;} } */import java.util.*; public class Solution {public ListNode deleteDuplication(ListNode pHead) {//初步想想法&#xff1a; 弄一个hashmap 然后进行key存储起来。然后 如果存…

[Buuctf] [MRCTF2020] Xor

运行 1.查壳 32位exe文件&#xff0c;没有壳 2.用32位IDA打开 找到main函数&#xff0c;F5查看伪代码&#xff0c;但是这里会弹出一个窗口 函数分析失败&#xff01;&#xff01; 这里我在看别人的题解时发现一种玄学方式解决了这个问题 窗口里面弹出了一个地址401095&…

鸿蒙Harmony应用开发—ArkTS声明式开发(模态转场设置:半模态转场)

通过bindSheet属性为组件绑定半模态页面&#xff0c;在组件插入时可通过设置自定义或默认的内置高度确定半模态大小。 说明&#xff1a; 从API Version 10开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 不支持路由跳转。 bindSheet bind…

【工具】Git的介绍与安装

目录 前言 1W&#xff1a;什么是Git&#xff1f; 2W&#xff1a;为什么使用Git&#xff1f; 3W&#xff1a;如何使用Git&#xff1f; Git的安装步骤 测试 3.1 桌面空白部分鼠标右击 3.2 选择 Open Git Bash here 3.3 输入 git -v 命令查看版本 Git区域分布 Git的工作…

Python列表及其操作详解,从此不再迷茫!

在前面的文章中&#xff0c;我们详细讲了六大数据类型中的数字类型&#xff0c;字符串类型。相信大家都能够熟练的掌握了。那么今天我们来讲解列表&#xff08;list&#xff09;。 这是一种常用且重要的数据类型&#xff0c;List可以用来存储一系列的元素&#xff0c;对于后期…

【漏洞复现】锐捷网络NBR700G 信息泄露

0x01 产品简介 锐捷网络NBR700G路由器是锐捷网络股份有限公司的一款无线路由设备。 0x02 漏洞概述 锐捷网络NBR700G路由器存在信息漏洞。未授权的攻击者可以通过该漏洞获取敏感信息。 0x03 测绘语句 fofa&#xff1a;body"系统负荷过高&#xff0c;导致网络拥塞&…

[LeetCode][LCR149]彩灯装饰记录 I——二叉树的层序遍历

题目 LCR 149. 彩灯装饰记录 I 给定一棵圣诞树&#xff0c;记作根节点为 root 的二叉树&#xff0c;节点值为该位置装饰彩灯的颜色编号。按照从左到右的顺序返回每一层彩灯编号。 示例 1&#xff1a; 输入&#xff1a;root [8,17,21,18,null,null,6] 输出&#xff1a;[8,17,…

【Python-Docx库】Word与Python的完美结合

今天给大家分享Python处理Word的第三方库&#xff1a;Python-Docx。 什么是Python-Docx&#xff1f; Python-Docx是用于创建和更新Microsoft Word&#xff08;.docx&#xff09;文件的Python库。 日常需要经常处理Word文档&#xff0c;用Python的免费第三方包&#xff1a;Pyt…

Vue3学习记录(六)--- 组合式API之依赖注入和异步组件

一、依赖注入 1、简介 ​ 在前面的笔记中&#xff0c;我们学习过父组件向子组件传递数据时&#xff0c;需要借助props来实现。但如果父组件想要向孙子组件传递数据&#xff0c;那就要连续使用两层props逐级向下传递&#xff0c;如果要接收数据的是更深层的后代组件&#xff0…