当前位置: 首页 > news >正文

【UCB CS 61B SP24】Lecture 22 23: Tree and Graph Traversals, DFS, BFS 学习笔记

本文讲解了二叉树的四种遍历方式,以及如何通过前/后序遍历与中序遍历重建出二叉树,接着介绍了新的非线性数据结构:图,详细讲解了图的存储方式与遍历方式,最后使用 Java 基于邻接表的存储方式实现了图与 DFS、BFS 两种遍历方式。

1. 二叉树的遍历与创建

1.1 遍历方式

二叉树的遍历方式有四种:前序遍历(Preorder Traversal)、中序遍历(Inorder Traversal)、后序遍历(Postorder Traversal)以及层序遍历(Levelorder Traversal)。

在这里插入图片描述

(1)前序遍历

  • 顺序:根节点 → 左子树 → 右子树
  • 特点:先访问根节点,再递归遍历左子树和右子树。
  • 应用:复制树的结构。

(2)中序遍历

  • 顺序:左子树 → 根节点 → 右子树
  • 特点:先遍历左子树,再访问根节点,最后遍历右子树。
  • 应用:对二叉搜索树(BST)按升序输出节点(在 BST 那节课实现过一次了)。

(3)后序遍历

  • 顺序:左子树 → 右子树 → 根节点
  • 特点:先递归遍历左右子树,最后访问根节点。
  • 应用:删除树或计算表达式树。

(4)层序遍历

  • 顺序:按层级从上到下、从左到右逐层访问节点。
  • 特点:使用队列辅助实现,非递归。
  • 应用:按层级分析树的结构。

只要结合图片理解了这几种遍历逻辑后实现起来就不难,递归很适合用来实现前三种遍历方式,而且代码几乎一样,只是递归子树与输出节点之间的顺序不一样,Java 实现树的遍历代码如下:

package CS61B.Lecture22;import java.util.LinkedList;
import java.util.Queue;class TreeNode<T> {T val;TreeNode<T> left;TreeNode<T> right;public TreeNode(T val) {this.val = val;this.left = null;this.right = null;}
}public class BinaryTreeTraversal {/** 前序遍历 */public static void preOrderTraversal(TreeNode root) {if (root == null) return;System.out.print(root.val + " ");preOrderTraversal(root.left);preOrderTraversal(root.right);}/** 中序遍历 */public static void inOrderTraversal(TreeNode root) {if (root == null) return;inOrderTraversal(root.left);System.out.print(root.val + " ");inOrderTraversal(root.right);}/** 后序遍历 */public static void postOrderTraversal(TreeNode root) {if (root == null) return;postOrderTraversal(root.left);postOrderTraversal(root.right);System.out.print(root.val + " ");}/** 层序遍历 */public static void levelOrderTraversal(TreeNode root) {Queue<TreeNode> Q = new LinkedList<>();Q.offer(root);while (Q.peek() != null) {TreeNode node = Q.poll();System.out.print(node.val + " ");if (node.left != null) Q.offer(node.left);if (node.right != null) Q.offer(node.right);}}/** 测试 */public static void main(String[] args) {// 构建示例二叉树//       D//   B       F// A   C   E   GTreeNode<Character> root = new TreeNode<>('D');root.left = new TreeNode<>('B');root.right = new TreeNode<>('F');root.left.left = new TreeNode<>('A');root.left.right = new TreeNode<>('C');root.right.left = new TreeNode<>('E');root.right.right = new TreeNode<>('G');preOrderTraversal(root);  // D B A C F E GSystem.out.println();inOrderTraversal(root);  // A B C D E F GSystem.out.println();postOrderTraversal(root);  // A C B E G F DSystem.out.println();levelOrderTraversal(root);  // D B F A C E GSystem.out.println();}
}

1.2 递归建树

在已知前/后序遍历与中序遍历的结果时,我们可以根据遍历结果把二叉树重建出来,其原理如下:

  • 必须包含中序遍历:中序的“左根右”结构是分割左右子树的关键。
  • 前序/后序提供根节点:前序首元素或后序末元素为根节点。
  • 唯一性条件:仅当已知树是满二叉树时,前序 + 后序可唯一确定二叉树。

前序 + 中序构建二叉树的核心思想为:

  • 找出根节点:前序数组的第一个元素即为根节点。
  • 分割中序数组:根据根节点将中序数组分为左子树和右子树。
  • 分割前序数组:根据左子树的节点数量,确定前序数组中左子树和右子树的范围(左子树的节点在前序数组中一定是在根节点之后连续分布,左子树后剩余的其他节点即为右子树节点)。
  • 递归构建:递归处理左子树和右子树。

根据前序遍历与中序遍历创建二叉树的过程如下图所示,其中红色表示当前正在处理的根节点,紫色表示已经创建好节点,绿色表示要递归处理的左子树,蓝色表示要递归处理的右子树:

在这里插入图片描述

  • 步骤一:前序数组的第一个元素 D 为根节点,在中序数组中找到 D 并建立根节点,然后将 D 的两侧分为左右子树,首先递归在左子树 [B, A, C] 中处理;
  • 步骤二:左子树 [B, A, C] 的第一个元素 B 为根节点,在中序数组中找到 B 并建立根节点,然后将 B 的两侧分为左右子树,首先递归在左子树 [A] 中处理;
  • 步骤三:左子树 [A] 的第一个元素 A 为根节点,在中序数组中找到 A 并建立根节点,A 的两侧要么为空要么为已经建好的节点,说明 A 已经是叶子节点了,回溯到 B,递归在右子树 [C] 中处理;
  • 步骤四:右子树 [C] 的第一个元素 C 为根节点,在中序数组中找到 C 并建立根节点,C 的两侧均为已经建好的节点,说明 C 已经是叶子节点了,回溯到 BB 的左右子树已经递归建好树了,回溯到 D,递归在右子树 [F, E, G] 中处理;
  • 后续步骤原理与之前一样,就不继续讲解了。

后序 + 中序构建二叉树的核心思想为:

  • 找出根节点:后序数组的最后一个元素即为根节点。
  • 分割中序数组:根据根节点分割中序数组。
  • 分割后序数组:根据左子树的节点数量,确定后序数组中左子树和右子树的范围。
  • 递归构建:递归处理左子树和右子树。

Java 实现递归建树代码如下,用到的节点 TreeNode 与遍历方法为上一小节中实现的:

package CS61B.Lecture22;public class BuildBinaryTree {/** 根据前序 + 中序遍历构建二叉树 */public static TreeNode buildTreeFromPreIn(Comparable[] pre, Comparable[] in) {return buildTreeFromPreIn(pre, 0, pre.length - 1, in, 0, in.length - 1);}/** 递归建树 */private static TreeNode buildTreeFromPreIn(Comparable[] pre, int preStart, int preEnd,Comparable[] in, int inStart, int inEnd) {if (preStart > preEnd) return null;  // 终止条件:前序数组为空TreeNode root = new TreeNode(pre[preStart]);  // 前序数组的第一个元素是当前子树的根节点int k = inStart;while (in[k].compareTo(pre[preStart]) != 0) k++;  // 在中序数组中找到根节点的位置int leftChildNums = k - inStart;  // 计算左子树的节点数量// 递归构建左子树和右子树root.left = buildTreeFromPreIn(pre, preStart + 1, preStart + leftChildNums, in, inStart, k - 1);root.right = buildTreeFromPreIn(pre, preStart + leftChildNums + 1, preEnd, in, k + 1, inEnd);return root;}/** 根据后序 + 中序遍历构建二叉树 */public static TreeNode buildTreeFromPostIn(Comparable[] post, Comparable[] in) {return buildTreeFromPostIn(post, 0, post.length - 1, in, 0, in.length - 1);}/** 递归建树 */private static TreeNode buildTreeFromPostIn(Comparable[] post, int postStart, int postEnd,Comparable[] in, int inStart, int inEnd) {if (postStart > postEnd) return null;  // 终止条件:后序数组为空TreeNode root = new TreeNode(post[postEnd]);  // 后序数组的最后一个元素是当前子树的根节点int k = inStart;while (in[k].compareTo(post[postEnd]) != 0) k++;  // 在中序数组中找到根节点的位置int leftChildNums = k - inStart;  // 计算左子树的节点数量// 递归构建左子树和右子树root.left = buildTreeFromPostIn(post, postStart, postStart + leftChildNums - 1, in, inStart, k - 1);root.right = buildTreeFromPostIn(post, postStart + leftChildNums, postEnd - 1, in, k + 1, inEnd);return root;}/** 测试 */public static void main(String[] args) {Character[] preorder = {'D', 'B', 'A', 'C', 'F', 'E', 'G'};Character[] inorder = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};Character[] postorder = {'A', 'C', 'B', 'E', 'G', 'F', 'D'};// 根据前序 + 中序遍历构建二叉树TreeNode rootFromPreIn = buildTreeFromPreIn(preorder, inorder);BinaryTreeTraversal.preOrderTraversal(rootFromPreIn);  // D B A C F E GSystem.out.println();BinaryTreeTraversal.inOrderTraversal(rootFromPreIn);  // A B C D E F GSystem.out.println();// 根据后序 + 中序遍历构建二叉树TreeNode rootFromPostIn = buildTreeFromPostIn(postorder, inorder);BinaryTreeTraversal.postOrderTraversal(rootFromPostIn);  // A C B E G F DSystem.out.println();BinaryTreeTraversal.inOrderTraversal(rootFromPostIn);  // A B C D E F GSystem.out.println();}
}

2. 图的概念及其遍历方式

2.1 介绍

与树类似,图(Graph)也是一种非线性数据结构,由顶点(Vertex/Node)和(Edge)组成。

  • 顶点:图的基本元素,表示实体,可以存储数据(如用户 ID、城市名称等)。
  • 边:表示顶点之间的关系(如社交关系、道路、超链接等),其中又分为简单边(连接两个顶点)、带权边(附加数值信息如距离、成本)以及自环边(顶点与自身相连的边)。
  • 数学表示:通常表示为 G = ( V , E ) G = (V, E) G=(V,E),其中 V V V 是顶点集合, E E E 是边集合。
  • 路径(Path):由顶点序列 v 1 , v 2 , … , v n v_1, v_2, \dots, v_n v1,v2,,vn 组成,其中每对相邻顶点由边连接,路径分为简单路径(路径中不重复经过顶点)与(起点和终点相同的路径)。

图有多种类型,分为有向图、无向图、有环图、无环图、且图的边是可以带权重的。其中无向图的边没有方向,若顶点 u u u v v v 之间有边,则 ( u , v ) (u, v) (u,v) ( v , u ) (v, u) (v,u) 表示同一概念;有向图的边表示为 < u , v > <u, v> <u,v>,表示从 u u u 指向 v v v

在这里插入图片描述

其他特殊图:

  • 完全图:每对顶点之间都有边;
  • 稀疏图与稠密图:边数远少于 V 2 V^2 V2 的图为稀疏图,反之为稠密图;
  • 连通图:任意两个顶点之间都有路径;
  • 树:无环的连通图(树是图的特例)。

图的相关术语:

  • 度(Degree):与顶点相连的边数。在有向图中又分为入度(In-degree)和出度(Out-degree)。
  • 子图(Subgraph):由原图的部分顶点和边组成。
  • 连通分量(Connected Component):无向图中的极大连通子图。
  • 强连通图(Strongly Connected Graph):有向图中任意两顶点互相可达。

2.2 图的存储与遍历方式

图有以下几种存储方式:

(1) 邻接矩阵(Adjacency Matrix)

  • 实现方法:使用二维数组 G G G 表示,其中 G [ i ] [ j ] = t r u e G[i][j] = true G[i][j]=true 表示顶点 i i i j j j 之间有边,否则表示无边。无向图的邻接矩阵一定是对称的
  • 优点:能够快速判断两顶点是否邻接,时间复杂度为 O ( 1 ) O(1) O(1)
  • 缺点:数组的宽高取决于顶点数,空间复杂度为 O ( V 2 ) O(V^2) O(V2),不适合稀疏图。

在这里插入图片描述

(2) 邻接表(Adjacency List)

  • 实现方法:每个顶点维护一个链表,存储其邻接的顶点。
  • 优点:空间复杂度为 O ( V + E ) O(V + E) O(V+E),适合稀疏图。
  • 缺点:判断两顶点是否邻接需要遍历链表,时间复杂度为 O ( V ) O(V) O(V)

在这里插入图片描述

(3) 其他存储方式

  • 边列表(Edge List):直接存储所有边的集合。
  • 邻接多重表(Adjacency Multilist):适用于无向图,优化边存储。

图的遍历方式最常用的有两种,分别是深度优先搜索(Depth-First Search,DFS)与广度优先搜索(Breadth-First Search,BFS)。

DFS 的核心思想是从起点出发,尽可能深地探索分支,直到无法继续,再回溯到上一个分叉点搜索其他分支,一般使用递归实现,优先访问未探索的邻接顶点。DFS 适用于拓扑排序、连通性检测、寻找路径、解决迷宫问题。

BFS 的核心思想是从起点出发,逐层向外扩展,先访问完最近的所有邻接顶点,再访问下一层,一般使用队列实现,保证按层遍历。BFS 适用于最短路径(无权图)、社交网络中的层级关系、广播消息。

我们通过下图来简单说明一下 DFS 与 BFS 的区别,假设我们想从起点 S 开始遍历,走到终点 T 的位置结束,那么这两种搜索方式的过程可能是下面这样:

  • DFS:假如第一步先搜到了 1,那么遵循一条分支走到底的原则,DFS 会先搜索完 1 -> 2 -> 5 -> 6 这条分支,发现没见到终点,因此开始回溯,而一路上的节点都没有分支,因此回溯到起点后才选另一条分支 3,在这条分支上继续往下搜索:3 -> 8,找到终点结束搜索。如果我们不结束继续搜索那么 DFS 就会从 8 继续往下搜到 4,因为只要当前有路可以走 DFS 就会一直走完,而不会回到起点走 0 -> 4 这条路。
  • BFS:在起点时 BFS 就会将与其相邻的所有节点加入队列:Q = [1, 3, 4, 7],然后开始遍历第一个节点 1,遍历的时候继续将当前节点相邻的点加入队列,此时 Q = [3, 4, 7, 2],然后我们下一个遍历的队头节点是 3,遍历的时候发现与其相连的节点 8,加入队列:Q = [4, 7, 2, 8]。因此 BFS 是从起点开始,先遍历完与之相连接的最近的节点:1 -> 3 -> 4 -> 7,然后才会向外扩展到第二近的那层:2 -> 8,以此类推。

在这里插入图片描述

我们用 Java 实现一下这两种搜索方式,图采用邻接表的形式存储,测试时构建的图与上图一致,代码不难理解:

package CS61B.Lecture22;import java.util.LinkedList;
import java.util.List;
import java.util.Queue;public class Graph {private final int V;  // 节点数量private final LinkedList<Integer>[] adj;  // 邻接表public Graph(int v) {V = v;adj = new LinkedList[v];for (int i = 0; i < v; i++)adj[i] = new LinkedList<>();  // 每个节点都用一个列表存放其能到达的其他节点序号}/** 添加边 */public void addEdge(int u, int v) {adj[u].add(v);  // 将 v 添加到 u 的邻接表,表示 u 有一条边能走到 vadj[v].add(u);  // 无向图还需要反向添加,表示 v 也能走到 u}/** 深度优先搜索 */public void DFS(int s) {boolean[] vis = new boolean[V];  // 标记某个节点是否已经访问过System.out.print("DFS Result: ");DFS(s, vis);System.out.println();}/** DFS 递归实现 */private void DFS(int u, boolean[] vis) {vis[u] = true;  // 标记当前节点已访问System.out.print(u + " ");for (int v : adj[u])  // 遍历当前节点 u 的邻接表if (!vis[v]) DFS(v, vis);  // 如果 u 能走到 v 且 v 还未访问则递归搜索 v}/** 广度优先搜索 */public void BFS(int s) {System.out.print("BFS Result: ");boolean[] vis = new boolean[V];Queue<Integer> q = new LinkedList<>(List.of(s));vis[s] = true;while (!q.isEmpty()) {int u = q.poll();System.out.print(u + " ");for (int v : adj[u])if (!vis[v]) {  // 将所有未访问的邻接顶点加入队列q.add(v);vis[v] = true;}}System.out.println();}/** 测试 */public static void main(String[] args) {Graph g = new Graph(10);for (int i : List.of(1, 3, 4, 7)) g.addEdge(0, i);g.addEdge(1, 2);g.addEdge(2, 5);g.addEdge(5, 6);g.addEdge(3, 8);g.addEdge(4, 8);g.DFS(0);  // DFS Result: 0 1 2 5 6 3 8 4 7g.BFS(0);  // BFS Result: 0 1 3 4 7 2 8 5 6}
}

相关文章:

【UCB CS 61B SP24】Lecture 22 23: Tree and Graph Traversals, DFS, BFS 学习笔记

本文讲解了二叉树的四种遍历方式&#xff0c;以及如何通过前/后序遍历与中序遍历重建出二叉树&#xff0c;接着介绍了新的非线性数据结构&#xff1a;图&#xff0c;详细讲解了图的存储方式与遍历方式&#xff0c;最后使用 Java 基于邻接表的存储方式实现了图与 DFS、BFS 两种遍…...

Redis100道高频面试题

一、Redis基础 Redis是什么&#xff1f;主要应用场景有哪些&#xff1f; Redis 是一个开源的、基于内存的数据结构存储系统&#xff0c;支持多种数据结构&#xff08;如字符串、哈希、列表、集合等&#xff09;&#xff0c;可以用作数据库、缓存和消息中间件。 主要应用场景&…...

Mac OS Homebrew更换国内镜像源(中科大;阿里;清华)

omebrew官方的源一般下载包之类的会很慢&#xff0c;所以通常我们都是用国内的镜像源来代替&#xff0c;这样会提高我们的效率。Homebrew主要有四个部分组成: brew、homebrew-core 、homebrew-bottles、homebrew-cask。 代码语言&#xff1a;javascript 代码运行次数&#xf…...

excel vlookup的精确查询、模糊查询、反向查询、多列查询

目录 入门 精确查询 模糊查询 反向查询 (搭配 if 函数) 多列查询 (搭配 match 函数) 入门 精确查询 需求: 查找 学生编号是008 所在的班级 操作: 在I2单元格输入公式如下,VLOOKUP(H2,B1:E12,4,FALSE), 得出结果 看一下vlookup 公式每一个参数应该怎么写? 语法: vlookup…...

linux的文件系统及文件类型

目录 一、Linux支持的文件系统 二、linux的文件类型 2.1、普通文件 2.2、目录文件 2.3、链接文件 2.4、字符设备文件: 2.5、块设备文件 2.6、套接字文件 2.7、管道文件 三、linux的文件属性 3.1、关于权限部分 四、Linux的文件结构 五、用户主目录 5.1、工作目录…...

MySQL 安装配置(完整教程)

文章目录 一、MySQL 简介二、下载 MySQL三、安装 MySQL四、配置环境变量五、配置 MySQL 5.1 初始化 MySQL5.2 启动 MySQL 服务 六、修改 MySQL 密码七、卸载 MySQL八、结语 一、MySQL 简介 MySQL 是一款广泛使用的开源关系型数据库管理系统&#xff08;RDBMS&#xff09;&am…...

C# Unity 唐老狮 No.4 模拟面试题

本文章不作任何商业用途 仅作学习与交流 安利唐老狮与其他老师合作的网站,内有大量免费资源和优质付费资源,我入门就是看唐老师的课程 打好坚实的基础非常非常重要: 全部 - 游习堂 - 唐老狮创立的游戏开发在线学习平台 - Powered By EduSoho 如果你发现了文章内特殊的字体格式,…...

给没有登录认证的web应用添加登录认证(openresty lua实现)

这阵子不是deepseek火么&#xff1f;我也折腾了下本地部署&#xff0c;ollama、vllm、llama.cpp都弄了下&#xff0c;webui也用了几个&#xff0c;发现nextjs-ollama-llm-ui小巧方便&#xff0c;挺适合个人使用的。如果放在网上供多人使用的话&#xff0c;得接入登录认证才好&a…...

R语言绘图:韦恩图

韦恩分析 韦恩分析&#xff08;Venn Analysis&#xff09;常用于可视化不同数据集之间的交集和并集。维恩图&#xff08;Venn diagram&#xff09;&#xff0c;也叫文氏图、温氏图、韦恩图、范氏图&#xff0c;用于显示元素集合重叠区域的关系型图表&#xff0c;通过图形与图形…...

STM32——串口通信 UART

一、基础配置 Universal Asynchronous Receiver Transmitter 异步&#xff0c;串行&#xff0c;全双工 TTL电平 &#xff1a;高电平1 低电平0 帧格式&#xff1a; 起始位1bit 数据位8bit 校验位1bit 终止位1bit NVIC Settings一栏使能接受中断。 之前有设置LCD&#xff0c;…...

【大模型基础_毛玉仁】1.3 基于Transformer 的语言模型

【大模型基础_毛玉仁】1.3 基于Transformer 的语言模型 1.3 基于Transformer 的语言模型1.3.1 Transformer1&#xff09;注意力层&#xff08;AttentionLayer&#xff09;2&#xff09;全连接前馈层&#xff08;Fully-connected Feedforwad Layer&#xff09;3&#xff09;层正…...

靶场(二)---靶场心得小白分享

开始&#xff1a; 看一下本地IP 21有未授权访问的话&#xff0c;就从21先看起 PORT STATE SERVICE VERSION 20/tcp closed ftp-data 21/tcp open ftp vsftpd 2.0.8 or later | ftp-anon: Anonymous FTP login allowed (FTP code 230) |_Cant get dire…...

大学至今的反思与总结

现在是2025年的3月5日&#xff0c;我大三下学期。 自大学伊始&#xff0c;我便以考研作为自己的目标&#xff0c;有时还会做自己考研上岸头部985,211&#xff0c;offer如潮水般涌来的美梦。 但是我却忽略了一点&#xff0c;即便我早早下定了决心去考研&#xff0c;但并没有早…...

【大模型】Llama 3.2 大语言模型初探:模型权重下载

文章目录 一、简介二、权重下载2.1 方法一&#xff1a;Meta 官网申请下载2.2 方法二&#xff1a;使用 hugging face 下载 一、简介 Llama&#xff08;Large Language Model Meta AI&#xff09;是 Meta&#xff08;原 Facebook&#xff09;开发的一系列开源大型语言模型。它的目…...

unity学习63,第2个小游戏:用fungus做一个简单对话游戏

目录 1 目标用fungus做一个简单的剧情对话游戏 1.1 先创建一个新的3D项目 1.2 fungus是什么 1.2.1 怎么获得 1.2 在AssetStore里搜索fungus (插件类)--千万别买收费的错的&#xff01; 1.3 fungus的官网 1.3.1 官网给的3个下载链接&#xff0c;unity的果然已经失效了 …...

笔记:代码随想录算法训练营day36:LeetCode1049. 最后一块石头的重量 II、494. 目标和、474.一和零

学习资料&#xff1a;代码随想录 1049.最后一块石头的重量II 力扣题目链接 思路&#xff1a;如何讲该问题转化为背包问题&#xff1a;还是对半分去碰&#xff0c;对半分去碰碰剩下的就是最小的。然后背包容量就是一半儿&#xff0c;物品重量等于物品价值等于stones[i] 和上…...

Elasticsearch:解锁深度匹配,运用Elasticsearch DSL构建闪电般的高效模糊搜索体验

目录 Elasticsearch查询分类 叶子查询 全文检索查询 match查询 multi_match查询 精确查询 term查询 range查询 复杂查询 bool查询简单应用 bool查询实现排序和分页 bool查询实现高亮 场景分析 问题思考 解决方案 search_after方案(推荐) point in time方案 方案…...

Android实现漂亮的波纹动画

Android实现漂亮的波纹动画 本文章讲述如何使用二维画布canvas和camera、矩阵实现二、三维波纹动画效果&#xff08;波纹大小变化、画笔透明度变化、画笔粗细变化&#xff09; 一、UI界面 界面主要分为三部分 第一部分&#xff1a;输入框&#xff0c;根据输入x轴、Y轴、Z轴倾…...

qt实践教学(编写一个代码生成工具)持续更新至完成———

前言&#xff1a; 我的想法是搭建一个和STM32cubemux类似的图形化代码生成工具&#xff0c;可以把我平时用到的代码整合一下全部放入这个软件中&#xff0c;做一个我自己专门的代码生成工具&#xff0c;我初步的想法是在下拉选框中拉取需要配置的功能&#xff0c;然后就弹出对…...

【数据结构】什么是栈||栈的经典应用||分治递归||斐波那契问题和归并算法||递归实现||顺序栈和链栈的区分

文章目录 &#x1f967;栈的初步理解&#xff1a;&#x1f967;易错&#xff1a;如何判断栈满&#x1f967;栈满理解&#x1f967;栈的基本运算&#x1f4da;栈操作的伪代码逻辑&#xff08;顺序和链栈&#xff09;&#x1f4d5;顺序栈运算实现&#xff1a;顺序栈的表示&#x…...

vue3(笔记)4.0 vueRouter.导航守卫.ElementPuls知识点

---vueRouter 创建路由: 完整写法(懒加载): 默认写法与vue2一致: 导入 然后 写成component: LoginPage import { createRouter, createWebHistory } from vue-routerconst router createRouter({history: createWebHistory(import.meta.env.BASE_URL), routes: [{path:/lo…...

[数字图像处理]实验三:直方图增强

目录 一、实验目的 二、实验原理 三、实验内容&#xff08;附代码&#xff09; 四、实验结果及分析 五、实验小结 一、实验目的 1.了解图像增强的意义和目的 2.掌握各种图像增强的基本原理和方法 3.使用MATLAB实现图像增强 二、实验原理 图像增强方法从增强的作用域…...

图像分类项目1:基于卷积神经网络的动物图像分类

1、选题背景及动机 在现代社会中&#xff0c;图像分类是计算机视觉领域的一个重要任务。动物图像分类具有广泛的应用&#xff0c;例如生态学研究、动物保护、农业监测等。通过对动物图像进行自动分类&#xff0c;可以帮助人们更好地了解动物种类、数量和分布情况&#xff0c;从…...

并发编程(线程池)面试题及原理

1. 执行原理/核心参数 1.1 核心参数 核心参数 corePoolSize 核心线程数目maximumPooISize 最大线程数目 &#xff08;核心线程&#xff0b;救急线程的最大数目&#xff09;keepAliveTime 生存时间- 救急线程的生存时间&#xff0c;生存时间内没有新任务&#xff0c;此线程资…...

初次使用 IDE 搭配 Lombok 注解的配置

前言 在 Java 开发的漫漫征程中&#xff0c;我们总会遇到各种提升效率的工具。Lombok 便是其中一款能让代码编写变得更加简洁高效的神奇库。它通过注解的方式&#xff0c;巧妙地在编译阶段为我们生成那些繁琐的样板代码&#xff0c;比如 getter、setter、构造函数等。然而&…...

云原生时代的技术桥梁

在数字化转型的大潮中&#xff0c;企业面临着数据孤岛、应用间集成复杂、高成本与低效率等问题。这些问题不仅阻碍了企业内部信息的流通和资源的共享&#xff0c;也影响了企业对外部市场变化的响应速度。当前&#xff0c;这一转型过程从IT角度来看&#xff0c;已然迈入云原生时…...

2024四川大学计算机考研复试上机真题

2024四川大学计算机考研复试上机真题 2024四川大学计算机考研复试机试真题 历年四川大学计算机考研复试机试真题 在线评测&#xff1a;https://app2098.acapp.acwing.com.cn/ 分数求和 题目描述 有一分数序列&#xff1a; 2/1 3/2 5/3 8/5 13/8 21/13… 求出这个数列的前 …...

【GPU使用】如何在物理机和Docker中指定GPU进行推理和训练

我的机器上有4张H100卡&#xff0c;我现在只想用某一张卡跑程序&#xff0c;该如何设置。 代码里面设置 import os # 记住要写在impot torch前 os.environ[CUDA_VISIBLE_DEVICES] "0, 1"命令行设置 export CUDA_VISIBLE_DEVICES0,2 # Linux 环境 python test.py …...

汽车免拆诊断案例 | 2023款丰田雷凌汽油版车行驶中偶尔出现通信故障

故障现象  一辆2023款丰田雷凌汽油版车&#xff0c;搭载1.5 L发动机&#xff0c;累计行驶里程约为4700 km。车主反映&#xff0c;行驶中偶尔组合仪表上的发动机转速信号丢失&#xff0c;转向变重&#xff0c;且有“闯车”感&#xff0c;同时车辆故障警报蜂鸣器鸣响。 故障诊断…...

千里科技亮相吉利AI智能科技发布会,共启“AI+车”新纪元

今天&#xff0c;在三亚举行的吉利AI智能科技发布会上&#xff0c;千里科技董事长印奇发表了主题为《从“车AI”到“AI车”》的演讲。印奇重点分享了对于“AI车”未来趋势的判断&#xff0c;并重点介绍了在吉利AI科技生态体系下&#xff0c;围绕智驾、智舱等领域的创新合作。基…...

汽车零部件厂如何选择最适合的安灯系统解决方案

在现代制造业中&#xff0c;安灯系统作为一种重要的生产管理工具&#xff0c;能够有效提升生产线的异常处理效率&#xff0c;确保生产过程的顺畅进行。对于汽车零部件厂来说&#xff0c;选择一套适合自身生产需求的安灯系统解决方案尤为重要。 一、安灯系统的核心功能 安灯系统…...

spring boot + vue 搭建环境

参考文档&#xff1a;https://blog.csdn.net/weixin_44215249/article/details/117376417?fromshareblogdetail&sharetypeblogdetail&sharerId117376417&sharereferPC&sharesourceqxpapt&sharefromfrom_link. spring boot vue 搭建环境 一、浏览器二、jd…...

spaCy 入门:自然语言处理的高效工具

spaCy 入门&#xff1a;自然语言处理的高效工具 引言 spaCy 是一个功能强大的开源 Python 库&#xff0c;专注于工业级的自然语言处理&#xff08;NLP&#xff09;。它以其高效的性能、简洁的 API 和对多种语言的支持而闻名。无论是进行文本分析、信息提取还是构建智能聊天机…...

Stable Diffusion模型高清算法模型类详解

Stable Diffusion模型高清算法模型类详细对比表 模型名称核心原理适用场景参数建议显存消耗细节增强度优缺点4x-UltraSharp残差密集块(RDB)结构优化纹理生成真实人像/建筑摄影重绘幅度0.3-0.4&#xff0c;分块尺寸768px★★★★★☆皮肤纹理细腻&#xff0c;但高对比场景易出现…...

数据结构:八大排序(冒泡,堆,插入,选择,希尔,快排,归并,计数)详解

目录 一.冒泡排序 二.堆排序 三.插入排序 四.选择排序 五.希尔排序 六.快速排序 1.Lomuto版本&#xff08;前后指针法&#xff09; 2.Lomuto版本的非递归算法 3.hoare版本&#xff08;左右指针法&#xff09; 4.挖坑法找分界值&#xff1a; 七.归并排序 八.计数排序…...

QT-对象树

思维导图 写1个Widget窗口&#xff0c;窗口里面放1个按钮&#xff0c;按钮随便叫什么 创建2个Widget对象 Widget w1,w2 w1.show() w2不管 要求&#xff1a;点击 w1.btn ,w1隐藏&#xff0c;w2显示 点击 w2.btn ,w2隐藏&#xff0c;w1 显示 #include <QApplication> #inc…...

随机播放音乐 伪随机

import java.util.*;/*** https://cloud.tencent.com.cn/developer/news/1045747* 伪随机播放音乐*/ public class MusicPlayer {private List<String> allSongs; // 所有歌曲列表private List<String> playedSongs; // 已经播放过的歌曲列表private Map<String…...

spring boot打包插件的问题

在spring boot项目中声明了 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build> 执行mvn clean package&…...

海康摄像头接入流媒体服务器实现https域名代理播放

环境 操作系统&#xff1a;Ubuntu 22.04流媒体服务器&#xff1a;srs 官网安装教程srs开启GB28181协议 官网开启教程进行海康摄像头的配置 官网配置教程srs使用systemctl实现开机自启 官网配置教程 nginx配置说明 server {listen 80;server_name a.com;return 301 https://$…...

Stable Diffusion模型Pony系列模型深度解析

Stable Diffusion模型Pony系列模型深度解析 一、技术架构与核心特性 基于SDXL的深度优化 Pony系列模型以SDXL为基础框架&#xff0c;通过针对二次元/动漫风格的微调&#xff0c;强化了在该领域的生成能力&#xff0c;同时保留了对写实场景的兼容性‌。其训练数据特别侧重于人…...

性能巅峰对决:Rust vs C++ —— 速度、安全与权衡的艺术

??关注&#xff0c;带你探索Java的奥秘&#xff01;?? ??超萌技术攻略&#xff0c;轻松晋级编程高手&#xff01;?? ??技术宝库已备好&#xff0c;就等你来挖掘&#xff01;?? ??订阅&#xff0c;智趣学习不孤单&#xff01;?? ??即刻启航&#xff0c;编…...

【Kubernets】K8S内部nginx访问Service资源原理说明

文章目录 原理概述**一、核心概念****二、Nginx 访问 Service 的流程****1. Service 的作用****2. Endpoint 的作用****3. Nginx Pod 发起请求****(1) DNS 解析****(2) 流量到达 kube-proxy****(3) 后端 Pod 处理请求** **三、不同代理模式的工作原理****1. iptables 模式****2…...

Markdown HTML 图像语法

插入图片 Markdown ![图片描述](图片链接)一般来说&#xff0c;直接复制粘贴过来就行了&#xff0c;部分网页/应用可以拖拽&#xff0c;没人会真敲图片的链接吧…… 示例图片&#xff1a; ![Creeper?](https://i-blog.csdnimg.cn/direct/f5031c8c4f15421c9882d7eb23540b8…...

2503,D比C更易重构

我发现C程序很少超越其初始设计.问题是,很难重构C程序.如 struct S { int a; }; struct S s; s.a 3; struct S *p; p->a 3;即.用来直接访问,->用来间接访问.假设想把按值传递S改为按指针传递S.现在你必须更新每个使用,而不仅是声明. 这是它在D中的工作方式: struct …...

Scala 中 val 和对象内部状态的关系

在 Scala 中&#xff0c;val 用于声明不可变的变量&#xff0c;这意味着一旦 val 被赋值&#xff0c;它的引用&#xff08;即指向的内存地址&#xff09;就不能再改变。然而&#xff0c;这并不影响对象内部的状态&#xff08;即对象的属性&#xff09;是否可以改变。具体来说&a…...

疫情管理系统设计与实现(代码+数据库+LW)

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本疫情管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&a…...

记Android12上一个原生bug引起的system_server crash

一. 现象描述 近日测试上报一个几乎必现的crash&#xff0c;描述如下: 现象: launcher编辑状态与锁屏解锁交互时系统概率性重启 操作步骤: 进入launcher组件编辑状态按电源键灭屏后亮屏&#xff0c;锁屏界面上滑解锁launcher编辑状态向右或向左滑动重复1&#xff0c;2&#x…...

代码随想录算法训练营第六天|Leetcode454.四数相加II 383. 赎金信 15. 三数之和 18. 四数之和

15. 三数之和 建议&#xff1a;本题虽然和 两数之和 很像&#xff0c;也能用哈希法&#xff0c;但用哈希法会很麻烦&#xff0c;双指针法才是正解&#xff0c;可以先看视频理解一下 双指针法的思路&#xff0c;文章中讲解的&#xff0c;没问题 哈希法很麻烦。 题目链接/文章讲…...

大数据环境(单机版) Flume传输数据到Kafka

文章目录 前言一、准备二、安装三、配置环境变量四、修改配置4.1、kafka配置4.2、Flume配置 五、启动程序5.1、启动zk5.2、启动kafka5.3、启动flume 六、测试6.1、启动一个kafka终端&#xff0c;用来消费消息6.2、写入日志 其他 前言 flume监控指定目录&#xff0c;传输数据到…...

计算机毕业设计SpringBoot+Vue.js高校教师科研管理系统(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…...