Langchain系列文章目录

01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南
02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖
03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南
04-玩转 LangChain:从文档加载到高效问答系统构建的全程实战
05-玩转 LangChain:深度评估问答系统的三种高效方法(示例生成、手动评估与LLM辅助评估)
06-从 0 到 1 掌握 LangChain Agents:自定义工具 + LLM 打造智能工作流!
07-【深度解析】从GPT-1到GPT-4:ChatGPT背后的核心原理全揭秘
08-【万字长文】MCP深度解析:打通AI与世界的“USB-C”,模型上下文协议原理、实践与未来

Python系列文章目录

PyTorch系列文章目录

机器学习系列文章目录

深度学习系列文章目录

Java系列文章目录

JavaScript系列文章目录

Python系列文章目录

Go语言系列文章目录

Docker系列文章目录

数据结构与算法系列文章目录

01-【数据结构与算法-Day 1】程序世界的基石:到底什么是数据结构与算法?
02-【数据结构与算法-Day 2】衡量代码的标尺:时间复杂度与大O表示法入门
03-【数据结构与算法-Day 3】揭秘算法效率的真相:全面解析O(n^2), O(2^n)及最好/最坏/平均复杂度
04-【数据结构与算法-Day 4】从O(1)到O(n²),全面掌握空间复杂度分析
05-【数据结构与算法-Day 5】实战演练:轻松看懂代码的时间与空间复杂度
06-【数据结构与算法-Day 6】最朴素的容器 - 数组(Array)深度解析
07-【数据结构与算法-Day 7】告别数组束缚,初识灵活的链表 (Linked List)
08-【数据结构与算法-Day 8】手把手带你拿捏单向链表:增、删、改核心操作详解
09-【数据结构与算法-Day 9】图解单向链表:从基础遍历到面试必考的链表反转
10-【数据结构与算法-Day 10】双向奔赴:深入解析双向链表(含图解与代码)
11-【数据结构与算法-Day 11】从循环链表到约瑟夫环,一文搞定链表的终极形态
12-【数据结构与算法-Day 12】深入浅出栈:从“后进先出”原理到数组与链表双实现
13-【数据结构与算法-Day 13】栈的应用:从括号匹配到逆波兰表达式求值,面试高频考点全解析
14-【数据结构与算法-Day 14】先进先出的公平:深入解析队列(Queue)的核心原理与数组实现
15-【数据结构与算法-Day 15】告别“假溢出”:深入解析循环队列与双端队列
16-【数据结构与算法-Day 16】队列的应用:广度优先搜索(BFS)的基石与迷宫寻路实战
17-【数据结构与算法-Day 17】揭秘哈希表:O(1)查找速度背后的魔法
18-【数据结构与算法-Day 18】面试必考!一文彻底搞懂哈希冲突四大解决方案:开放寻址、拉链法、再哈希
19-【数据结构与算法-Day 19】告别线性世界,一文掌握树(Tree)的核心概念与表示法
20-【数据结构与算法-Day 20】从零到一掌握二叉树:定义、性质、特殊形态与存储结构全解析
21-【数据结构与算法-Day 21】精通二叉树遍历(上):前序、中序、后序的递归与迭代实现
22-【数据结构与算法-Day 22】玩转二叉树遍历(下):广度优先搜索(BFS)与层序遍历的奥秘
23-【数据结构与算法-Day 23】为搜索而生:一文彻底搞懂二叉搜索树 (BST) 的奥秘
24-【数据结构与算法-Day 24】平衡的艺术:图解AVL树,彻底告别“瘸腿”二叉搜索树
25-【数据结构与算法-Day 25】工程中的王者:深入解析红黑树 (Red-Black Tree)
26-【数据结构与算法-Day 26】堆:揭秘优先队列背后的“特殊”完全二叉树
27-【数据结构与算法-Day 27】堆的应用:从堆排序到 Top K 问题,一文彻底搞定!


文章目录

  • Langchain系列文章目录
  • Python系列文章目录
  • PyTorch系列文章目录
  • 机器学习系列文章目录
  • 深度学习系列文章目录
  • Java系列文章目录
  • JavaScript系列文章目录
  • Python系列文章目录
  • Go语言系列文章目录
  • Docker系列文章目录
  • 数据结构与算法系列文章目录
  • 摘要
  • 一、温故知新:堆的核心概念回顾
  • 二、堆排序 (Heap Sort):原地排序的艺术
    • 2.1 第一步:原地建堆 (Heapify)
        • (1)建堆过程图解
    • 2.2 第二步:排序阶段
        • (1)排序过程图解
    • 2.3 代码实现 (Java)
    • 2.4 性能分析
  • 三、Top K 问题:海量数据处理的利器
    • 3.1 问题定义与挑战
    • 3.2 解决方案:小顶堆的妙用
        • (1)算法流程
        • (2)为什么用最小堆?
    • 3.3 代码实现 (Java)
    • 3.4 复杂度分析与扩展
        • (1)复杂度分析
        • (2)举一反三
  • 四、总结


摘要

在上一篇文章中,我们学习了堆(Heap)这种特殊的完全二叉树结构及其核心操作。今天,我们将把理论付诸实践,深入探讨堆的两个杀手级应用:堆排序 (Heap Sort) 和经典的 Top K 问题。堆排序是一种高效的原地排序算法,理解它的原理能加深我们对堆结构的掌握。而 Top K 问题则是大数据和面试场景下的常客,通过堆可以找到极其优雅且高效的解决方案。本文将通过图解、代码和详尽的分析,带你彻底征服这两个知识点,让你无论在项目开发还是技术面试中都能游刃有余。

一、温故知新:堆的核心概念回顾

在深入应用之前,我们先快速回顾一下堆的关键特性,这将是理解后续内容的基础。

  • 结构:堆在逻辑上是一棵完全二叉树,在物理存储上通常使用数组来实现,从而节省了指针开销,并能方便地通过索引计算父子节点关系。
  • 特性
    • 最大堆 (Max-Heap):任意节点的值都不小于其子节点的值。堆顶元素是整个堆中的最大值。
    • 最小堆 (Min-Heap):任意节点的值都不大于其子节点的值。堆顶元素是整个堆中的最小值。
  • 核心操作
    • 插入 (Sift Up / 上浮):将新元素添加到数组末尾,然后通过与其父节点比较,一路向上调整,直到满足堆的性质。
    • 删除堆顶 (Sift Down / 下沉):将数组末尾元素替换堆顶,然后通过与其子节点比较,一路向下调整,直到满足堆的性质。

上图展示了一个最大堆及其在数组中的存储方式。父节点索引为 i,其左子节点为 2*i+1,右子节点为 2*i+2

二、堆排序 (Heap Sort):原地排序的艺术

堆排序是一种利用堆结构特性设计的选择排序。它的核心思想是:首先将待排序的序列构建成一个最大堆,然后依次将堆顶元素(当前最大值)与数组末尾元素交换,并缩小堆的范围,再对新的堆顶进行下沉操作以维持最大堆性质。 重复此过程,直到所有元素都被排序。

整个过程分为两大步:建堆排序

2.1 第一步:原地建堆 (Heapify)

给定一个无序数组,如何最高效地将其转换为一个堆?一个直观的想法是创建一个空堆,然后将数组中的元素逐个插入,时间复杂度为 O(nlog⁡n)O(n \log n)O(nlogn)。但存在一种更高效的原地建堆方法,其时间复杂度仅为 O(n)O(n)O(n)

该方法的核心思想是:从最后一个非叶子节点开始,自后向前、自下而上地对每个节点执行“下沉 (Sift Down)”操作

  • 为什么从最后一个非叶子节点开始? 因为叶子节点自身已经是一个合法的堆(没有子节点),无需调整。
  • 为什么自下而上? 因为当调整一个节点时,我们保证了它的子树已经满足堆的性质,这样只需将当前节点“下沉”到正确位置即可。
(1)建堆过程图解

假设我们有数组 [4, 10, 3, 5, 1, 2],我们要将其构建成一个最大堆。

  1. 定位:数组长度 n=6。最后一个非叶子节点的索引是 floor(n/2) - 1 = floor(6/2) - 1 = 2。该节点的值是 3
  2. 从索引 2 (值为 3) 开始下沉:节点 3 的子节点是 23 > 2,满足最大堆性质,无需交换。
  3. 从索引 1 (值为 10) 开始下沉:节点 10 的子节点是 5110 大于它们,满足性质,无需交换。
  4. 从索引 0 (值为 4) 开始下沉:节点 4 的子节点是 1034 < 10,不满足最大堆性质。将 4 与其较大的子节点 10 交换。交换后,数组变为 [10, 4, 3, 5, 1, 2]。被交换下去的 4 成为索引为 1 的节点,它没有子节点了(或者说它的新子节点51都比它小),下沉结束。

至此,建堆完成。最终的堆结构如下:

10
4
3
5
1
2

最终数组为 [10, 4, 3, 5, 1, 2]

2.2 第二步:排序阶段

建堆完成后,数组的第一个元素 arr[0] 就是当前序列的最大值。排序阶段的步骤如下:

  1. 将堆顶元素 arr[0] 与当前堆的最后一个元素 arr[i] 交换。此时,最大值被放到了数组的正确位置(末尾)。
  2. 将堆的大小减一(逻辑上将已排序的元素排除在外)。
  3. 对新的堆顶 arr[0] 执行“下沉”操作,以恢复最大堆的性质。
  4. 重复上述步骤,直到堆中只剩一个元素。
(1)排序过程图解

继续上面的例子,数组为 [10, 4, 3, 5, 1, 2],堆大小 heapSize = 6

  1. 第一次迭代

    • 交换 arr[0] (10) 和 arr[5] (2)。数组变为 [2, 4, 3, 5, 1, 10]
    • heapSize 减为 510 已被排序。
    • 对新堆顶 2 执行下沉。2 和其子节点 43 比较,与较大的 4 交换。数组变为 [4, 2, 3, 5, 1, 10]2 再与其新子节点 5 比较,与 5 交换。数组变为 [4, 5, 3, 2, 1, 10]。等等,下沉逻辑应该是与左右子节点中较大的那个交换。重新来:
    • 对新堆顶 2 执行下沉。子节点 434 更大。24 交换,数组变为 [4, 2, 3, 5, 1, 10]2 到了索引 1,它的子节点是 515 更大。25 交换。数组变为 [4, 5, 3, 2, 1, 10]。等等,逻辑错了。下沉应该在交换后的子树中进行。

    让我们重新梳理下沉逻辑:

    • 堆顶 2,子节点 4 (索引1) 和 3 (索引2)。4 > 2,交换。数组变为 [4, 4, 3, 5, 1, 10]2 到了索引 1
    • arr[0] (2) 与 arr[5] (10) 交换 -> [2, 4, 3, 5, 1, 10]
    • arr[0] (2) 在 heapSize=5 的范围内下沉。
    • i=0,左子 1 (值4),右子 2 (值3)。arr[1]>arr[2],所以和 arr[1] 比较。arr[0] < arr[1],交换 arr[0]arr[1]
    • 数组变为 [4, 2, 3, 5, 1, 10]
    • 现在 2 到了索引 1i=1,左子 3 (值5),右子 4 (值1)。arr[3]>arr[4],所以和 arr[3] 比较。arr[1] < arr[3],交换 arr[1]arr[3]
    • 数组变为 [4, 5, 3, 2, 1, 10]
    • 现在 2 到了索引 3,它没有子节点了,下沉结束。
    • 第一次迭代后,堆部分为 [5, 4, 3, 2, 1],数组为 [5, 4, 3, 2, 1, 10]
  2. 第二次迭代

    • heapSize = 5。交换 arr[0] (5) 和 arr[4] (1)。数组变为 [1, 4, 3, 2, 5, 10]
    • heapSize 减为 4510 已被排序。
    • 对新堆顶 1 执行下沉。与 4 交换 -> [4, 1, 3, 2, 5, 10]1 再与 2 交换 -> [4, 2, 3, 1, 5, 10]
    • 第二次迭代后,堆部分为 [4, 2, 3, 1],数组为 [4, 2, 3, 1, 5, 10]
  3. … 以此类推,直到整个数组有序:[1, 2, 3, 4, 5, 10]

2.3 代码实现 (Java)

public class HeapSort {public void sort(int[] arr) {if (arr == null || arr.length < 2) {return;}// 1. 构建最大堆 (从最后一个非叶子节点开始)// 数组长度为 n,则最后一个非叶子节点索引为 n/2 - 1for (int i = arr.length / 2 - 1; i >= 0; i--) {siftDown(arr, i, arr.length);}// 2. 排序阶段for (int i = arr.length - 1; i > 0; i--) {// 将堆顶元素(最大值)与末尾元素交换swap(arr, 0, i);// 交换后,堆大小减 1,并对新的堆顶进行下沉操作siftDown(arr, 0, i);}}/*** 下沉操作 (调整为最大堆)* @param arr 待调整的数组* @param index 要下沉的节点索引* @param heapSize 堆的大小(不是数组的长度)*/private void siftDown(int[] arr, int index, int heapSize) {int parentValue = arr[index]; // 先保存父节点的值,用于最后赋值// 循环直到当前节点没有左子节点 (2*index + 1 >= heapSize)for (int childIndex = 2 * index + 1; childIndex < heapSize; childIndex = 2 * childIndex + 1) {// 如果存在右子节点,并且右子节点比左子节点大,则定位到右子节点if (childIndex + 1 < heapSize && arr[childIndex + 1] > arr[childIndex]) {childIndex++;}// 如果父节点比最大的子节点还大,则无需下沉,直接跳出if (parentValue >= arr[childIndex]) {break;}// 否则,将子节点的值赋给父节点,继续向下比较arr[index] = arr[childIndex];index = childIndex; // 更新 index 为子节点索引,准备下一轮循环}// 循环结束后,将最初的父节点值放到最终的位置arr[index] = parentValue;}private void swap(int[] arr, int i, int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}
}

2.4 性能分析

  • 时间复杂度
    • 建堆过程:O(n)O(n)O(n)。这是一个精确的结论,虽然看起来是 n/2n/2n/2siftDown,但大部分 siftDown 的路径都很短。
    • 排序过程:进行了 n−1n-1n1 次交换和 siftDown 操作。每次 siftDown 的时间复杂度是 O(log⁡n)O(\log n)O(logn)。所以这部分是 O(nlog⁡n)O(n \log n)O(nlogn)
    • 总时间复杂度O(n)+O(nlog⁡n)=O(nlog⁡n)O(n) + O(n \log n) = O(n \log n)O(n)+O(nlogn)=O(nlogn)
  • 空间复杂度O(1)O(1)O(1)。堆排序是原地排序,只需要常数级别的额外空间用于交换。
  • 稳定性:堆排序是不稳定的。在 siftDown 和交换堆顶的过程中,相同大小的元素的相对顺序可能会被改变。

三、Top K 问题:海量数据处理的利器

Top K 问题是一个非常经典的面试题和工程问题,其描述通常是:从 N 个数据中,找出最大(或最小)的 K 个数,其中 N 的数量级可能非常大(如百万、十亿),无法一次性加载到内存中。

3.1 问题定义与挑战

例如,从 10 亿个搜索日志中,找出点击量最高的 10 个搜索词。

  • 挑战
    1. 内存限制:无法将 10 亿条数据全部加载到内存中进行排序。
    2. 效率要求:即使内存足够,对全部数据排序(时间复杂度 O(nlog⁡n)O(n \log n)O(nlogn))也是一种巨大的浪费,因为我们只关心前 K 个元素。

3.2 解决方案:小顶堆的妙用

堆是解决 Top K 问题的完美工具。这里有一个非常巧妙的设计:

要求解 “Top K 大” 的问题,我们使用一个容量为 K 的 “最小堆”。

(1)算法流程
  1. 创建一个大小为 K 的最小堆(优先队列)。
  2. 遍历数据源(N 个数据):
    a. 首先,读取前 K 个元素,直接全部放入最小堆中。此时堆被填满。
    b. 继续读取第 K+1 个元素 x
    * 将其与堆顶元素 heap_top(当前已发现的 K 个元素中的最小值)进行比较。
    * 如果 x > heap_top,说明 x 有资格进入 Top K 行列,而 heap_top 则被淘汰。具体操作是:弹出堆顶,并将 x 插入堆中
    * 如果 x <= heap_top,说明 x 连当前 Top K 的“门槛”都达不到,直接忽略。
  3. 遍历完所有 N 个数据后,堆中剩下的 K 个元素,就是我们要求解的 Top K 大的元素。
(2)为什么用最小堆?

最小堆的堆顶始终是堆中最小的元素。这个堆的作用就像一个“擂台”,堆顶就是“擂主”,只不过这个擂主是“守门员”,是当前 Top K 榜单中实力最弱的那个。任何新的挑战者,只需要和这个最弱的“守门员”比试即可。如果连最弱的都打不过,那肯定没资格上榜。如果打得过,就把它替换掉,成为新的(可能也是暂时的)“守门员”。

这种设计保证了堆中始终维护着当前为止遇到的 K 个最大元素,而堆顶就是这 K 个元素中的最小值,即 Top K 的“准入门槛”。

3.3 代码实现 (Java)

在 Java 中,PriorityQueue 默认就是最小堆,非常适合用来解决此问题。

import java.util.PriorityQueue;public class TopKFinder {/*** 找出数组中最大的 K 个数* @param arr 数据源数组* @param k 需要找出的元素数量* @return 包含最大 K 个数的数组*/public int[] findTopK(int[] arr, int k) {if (arr == null || arr.length < k || k <= 0) {// 返回空数组或抛出异常,根据业务需求决定return new int[0];}// 创建一个最小堆,容量为 k// PriorityQueue 在 Java 中默认是最小堆PriorityQueue<Integer> minHeap = new PriorityQueue<>(k);// 遍历数组for (int num : arr) {if (minHeap.size() < k) {// 如果堆未满,直接添加minHeap.offer(num);} else if (num > minHeap.peek()) {// 如果当前元素大于堆顶元素(当前 K 个中的最小值)// 弹出堆顶minHeap.poll();// 将当前元素入堆minHeap.offer(num);}}// 将堆中元素转换为数组返回int[] result = new int[k];for (int i = 0; i < k; i++) {result[i] = minHeap.poll();}return result;}
}

3.4 复杂度分析与扩展

(1)复杂度分析
  • 时间复杂度O(nlog⁡k)O(n \log k)O(nlogk)
    • 我们遍历了 N 个元素。
    • 对于每个元素,最多进行一次堆操作(offerpoll+offer)。堆的大小始终不超过 K,所以每次堆操作的时间复杂度是 O(log⁡k)O(\log k)O(logk)
    • 因此,总时间复杂度是 O(nlog⁡k)O(n \log k)O(nlogk)。当 K 远小于 N 时,这比 O(nlog⁡n)O(n \log n)O(nlogn) 高效得多。
  • 空间复杂度O(k)O(k)O(k)。我们需要一个大小为 K 的堆来存储临时的 Top K 元素。
(2)举一反三
  • 如何求解 “Top K 小”?
    • 思路完全相反:使用一个大小为 K 的最大堆
    • 遍历数据,如果新元素比堆顶(当前 K 个中的最大值)还小,就替换掉堆顶。
    • 时间复杂度依然是 O(nlog⁡k)O(n \log k)O(nlogk),空间复杂度是 O(k)O(k)O(k)

四、总结

本文我们深入探讨了堆的两种核心应用,将理论知识转化为了强大的编程武器。

  1. 堆排序 (Heap Sort):一种性能优秀的原地排序算法。其核心步骤是先用 O(n)O(n)O(n) 的时间复杂度原地建堆,然后通过 n−1n-1n1 次“交换堆顶与末尾元素”并“下沉”的操作完成排序,总时间复杂度为 O(nlog⁡n)O(n \log n)O(nlogn)
  2. 堆排序特性:时间复杂度稳定在 O(nlog⁡n)O(n \log n)O(nlogn),空间复杂度为 O(1)O(1)O(1),但它是一种不稳定排序
  3. Top K 问题:解决“从海量数据中找出最大/最小的 K 个数”问题的经典场景。堆提供了极其高效的解决方案。
  4. Top K 解法精髓:求解 Top K ,使用容量为 K 的最小堆;求解 Top K ,使用容量为 K 的最大堆。这种“反向思维”是关键。该算法的时间复杂度为 O(nlog⁡k)O(n \log k)O(nlogk),空间复杂度为 O(k)O(k)O(k),完美契合了大数据、低内存的场景需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/98039.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/98039.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/98039.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

企业即时通讯保障企业通讯安全,提升企业部门协作效率

在当今数字化转型的大潮中&#xff0c;企业即时通讯软件已从单纯的沟通工具&#xff0c;逐步演变为保障企业数据安全的核心基础设施。吱吱企业即时通讯软件通过“私有化部署全流程加密”的双重机制&#xff0c;为企业构建了一套集“通讯安全”与“部门协作”于一体的数字化解决…

《华为变革法:打造可持续进步的组织》读书笔记

推荐序一&#xff1a;变革是企业活下去的基础&#xff08;胡彦平&#xff09;华为前常务副总裁、变革指导委员会成员胡彦平在序言中强调&#xff0c;企业存续的核心命题是应对不确定性&#xff0c;而变革能力是破解这一命题的唯一答案。他以华为 30 余年的发展历程为例&#xf…

第二篇:排序算法的简单认识【数据结构入门】

排序算法的分类标准 时间复杂度分类 a. 简单排序算法&#xff1a;时间复杂度O(n)&#xff0c;冒泡排序、选择排序、插入排序&#xff1b; b. 高级排序算法&#xff1a;时间复杂度O(n logn)&#xff0c;快速排序、归并排序、堆排序&#xff1b; c. 线性排序算法&#xff1a;时间…

快速掌握Dify+Chrome MCP:打造网页操控AI助手

你是否曾经希望那些强大的开源大模型能更贴合你的专业领域&#xff0c;或者学会模仿你的行文风格&#xff1f;其实&#xff0c;实现这个目标的关键就在于“微调”。曾几何时&#xff0c;微调模型是大公司的专属游戏——动不动就需要几十张GPU和复杂的分布式训练技术。 而现在&…

单词记忆-轻松记忆10个实用英语单词(15)

1. repaint含义&#xff1a;重新油漆 读音标注&#xff1a;/ˌriːˈpeɪnt/ 例句&#xff1a;We need to repaint the walls after the repairs. 译文&#xff1a;修理完成后需要重新粉刷墙壁。 衍生含义&#xff1a;重新绘制&#xff08;图像场景&#xff09;&#xff1b;翻新…

visual studio快捷键

1.visual studio代码格式化快捷键 1.CtrlA&#xff08;全选&#xff09; 2.CtrlK 3.CtrlF2.多行注释 1.Ctrlk 2.Ctrlc2.多行取消注释 1.Ctrlk 2.Ctrlu

Django全栈班v1.04 Python基础语法 20250913 下午

练习&#xff1a;个人信息收集器 任务&#xff1a;创建一个个人信息收集和展示程序 要求&#xff1a; 收集用户的姓名&#xff0c;年龄&#xff0c;城市&#xff0c;爱好验证年龄输入&#xff0c;必须是正数格式化输出用户信息计算用户出生年份 name input("请输入姓名&a…

学习海康VisionMaster之字符缺陷检测

前言&#xff1a;差不多三个月没更新了&#xff0c;天天码代码&#xff0c;实在是太忙了&#xff0c;有时候也在想这么忙到底是不是工作方法的问题&#xff0c;怎么样才能变成大师呢&#xff01; 一&#xff1a;进一步学习 今天学习下VisionMaster中的字符缺陷检测&#xff1…

若依4.8.1打包war后在Tomcat无法运行,404报错的一个解决方法

背景 最近使用若依4.8.1进行二次开发&#xff0c;接着尝试打包成war包进行部署&#xff0c;结果出现了404&#xff0c;提示“HTTP状态 404 - 未找到&#xff0c;请求的资源[/ruoyi-admin/]不可用”&#xff0c;翻了网上的教程&#xff0c;包括看了官方的解疑都没有说到该情况。…

华清远见25072班网络编程学习day6

重点内容&#xff1a;数据库基本概念:数据&#xff08;Data&#xff09;&#xff1a;能够输入计算机并能被计算机程序识别和处理的信息集合数据 &#xff08;Database&#xff09;数据库是在数据库管理系统管理和控制之下&#xff0c;存放在存储介质上的数据集合重要概念&#…

机器学习-网络架构搜索

Neural Architecture Search&#xff08;NAS&#xff09; 一个神经网络有不同类型的超参数 拓扑结构&#xff1a;resnet&#xff0c;mobilenet 单独层&#xff1a;核大小&#xff0c;卷积层的通道&#xff0c;输出隐藏单元的个数NAS自动设计神经网络 如何设计搜索空间 如何探索…

云手机在办公领域中自动化的应用

云手机在办公自动化领域正逐渐展现出强大的潜力&#xff0c;以下是其在办公中自动化应用的多方面介绍&#xff1a;企业借助云手机搭载的办公软件&#xff0c;可实现文档处理自动化&#xff0c;对于重复性文档任务&#xff0c;如制作每月固定格式的销售报告、财务报表等&#xf…

c++多线程(3)------休眠函数sleep_for和sleep_until

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 这两个函数都定义在 头文件中&#xff0c;属于 std::this_thread 命名空间&#xff0c;用于让当前线程暂停执行一段时间。函数功能sleep_for(rel_time)让当前线程休眠一段相对时间&…

Intel RealSense D455深度相机驱动安装与运行

Intel RealSense D455深度相机安装过程遇到过一些报错&#xff0c;所以记录一下安装过程&#xff01;&#xff01;&#xff01;以后方便回顾。 1.安装最新的IntelRealSense SDK2.0 (1) 注册服务器的公钥 sudo apt-get update && sudo apt-get upgrade && su…

从异步到半同步:全面解读MySQL复制的数据一致性保障方案

MySQL 主从复制&#xff08;Replication&#xff09;是其最核心的高可用性和扩展性功能之一。它的原理是将一个 MySQL 实例&#xff08;称为主库 Master&#xff09;的数据变更&#xff0c;自动同步到另一个或多个 MySQL 实例&#xff08;称为从库 Slave&#xff09;的过程。下…

PostgreSQL GIN 索引揭秘

文章目录什么是GIN Index?示例场景GIN Index的原理GIN Index结构MetapageEntriesLeaf PagesEntry page 和 Leaf page 的关系Posting list 和posting tree待处理列表&#xff08;Pending List&#xff09;进阶解读GIN index索引结构总结什么是GIN Index? GIN (Generalized In…

开源多模态OpenFlamingo横空出世,基于Flamingo架构实现图像文本自由对话,重塑人机交互未来

注&#xff1a;此文章内容均节选自充电了么创始人&#xff0c;CEO兼CTO陈敬雷老师的新书《GPT多模态大模型与AI Agent智能体》&#xff08;跟我一起学人工智能&#xff09;【陈敬雷编著】【清华大学出版社】 清华《GPT多模态大模型与AI Agent智能体》书籍配套视频课程【陈敬雷…

电子衍射模拟:基于GPU加速的MATLAB/Julia实现

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;注册即送-H卡级别算力&#xff0c;80G大显存&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生更享专属优惠。 引言&#xff1a;电子衍射模拟的重要性与计算挑战 电子…

easyExcel动态应用案例

代码链接&#xff1a;https://download.csdn.net/download/ly1h1/919402991.案例说明&#xff1a;1.1.导入功能导入数据实现转换成 List<List<String>> headers和 List<List<String>> datas&#xff0c;后续补充可以与数据模型注解结合&#xff0c;形…

【数据结构入门】排序算法(5):计数排序

目录 1. 比较排序和非比较排序 2. 计数排序的原理 2.1 计数排序的弊端 3.代码复现 3.1 代码分析 3.2 排序核心 3.3 时间、空间复杂度 1. 比较排序和非比较排序 比较排序是根据排序元素的具体数值比较来进行排序&#xff1b;非比较排序则相反&#xff0c;非比较排序例如&…