归并排序排序总结
1. 归并排序
1.1 基本思想
归并排序(Merge Sort)是采用分治法(Divide and Conquer)的一个非常典型的应用。它的基本思想是将一个数组分成两个子数组,分别对这两个子数组进行排序,然后将排好序的子数组合并成一个最终的有序数组。具体来说,归并排序主要分为两个步骤:
- 分解(Divide):将当前数组从中间分成两个子数组,递归地对这两个子数组进行分解,直到每个子数组只包含一个元素(因为单个元素的数组是有序的)。
- 合并(Merge):将两个有序的子数组合并成一个更大的有序数组。不断重复这个合并过程,直到所有子数组合并成一个完整的有序数组。
1.2 算法步骤
- 分解阶段:
- 找到数组的中间位置
mid
,将数组分为左右两部分,即left = arr[0...mid]
和right = arr[mid + 1...n-1]
,其中n
是数组的长度。 - 递归地对
left
和right
子数组进行分解,直到子数组的长度为 1。
- 找到数组的中间位置
- 合并阶段:
- 创建一个临时数组
temp
用于存储合并后的结果。 - 比较
left
和right
子数组的元素,将较小的元素依次放入temp
数组中。 - 重复步骤 2,直到
left
或right
子数组中的元素全部放入temp
数组。 - 将剩余的元素(如果有)直接放入
temp
数组的末尾。 - 将
temp
数组中的元素复制回原数组。
- 创建一个临时数组
1.3 代码实现
#include <iostream>
#include <vector>// 合并两个有序数组
void merge(std::vector<int>& arr, int left, int mid, int right) {int n1 = mid - left + 1;int n2 = right - mid;// 创建临时数组std::vector<int> L(n1), R(n2);// 复制数据到临时数组 L[] 和 R[]for (int i = 0; i < n1; i++)L[i] = arr[left + i];for (int j = 0; j < n2; j++)R[j] = arr[mid + 1 + j];// 归并临时数组到 arr[left..right]int i = 0; // 初始化第一个子数组的索引int j = 0; // 初始化第二个子数组的索引int k = left; // 初始归并子数组的索引while (i < n1 && j < n2) {if (L[i] <= R[j]) {arr[k] = L[i];i++;} else {arr[k] = R[j];j++;}k++;}// 复制 L[] 的剩余元素while (i < n1) {arr[k] = L[i];i++;k++;}// 复制 R[] 的剩余元素while (j < n2) {arr[k] = R[j];j++;k++;}
}// 归并排序函数
void mergeSort(std::vector<int>& arr, int left, int right) {if (left < right) {// 找到中间点int mid = left + (right - left) / 2;// 递归排序左半部分mergeSort(arr, left, mid);// 递归排序右半部分mergeSort(arr, mid + 1, right);// 合并已排序的两部分merge(arr, left, mid, right);}
}// 打印数组
void printArray(const std::vector<int>& arr) {for (int num : arr)std::cout << num << " ";std::cout << std::endl;
}int main() {std::vector<int> arr = {38, 27, 43, 3, 9, 82, 10};std::cout << "Original array: ";printArray(arr);int n = arr.size();mergeSort(arr, 0, n - 1);std::cout << "Sorted array: ";printArray(arr);return 0;
}
1.4 复杂度分析
- 时间复杂度:归并排序的时间复杂度始终为 O ( n l o g n ) O(n log n) O(nlogn),无论输入数组的初始状态如何。这是因为每次分解数组的时间复杂度为 O ( l o g n ) O(log n) O(logn),而每次合并数组的时间复杂度为 O ( n ) O(n) O(n),所以总的时间复杂度为 O ( n l o g n ) O(n log n) O(nlogn)。
- 空间复杂度:归并排序的空间复杂度为 O ( n ) O(n) O(n),主要用于临时数组
temp
的存储。
1.5 优缺点
- 优点:
- 时间复杂度稳定,为 O ( n l o g n ) O(n log n) O(nlogn),适用于大规模数据的排序。
- 是一种稳定的排序算法,即相等元素的相对顺序在排序后不会改变。
- 缺点:
- 需要额外的 O ( n ) O(n) O(n) 空间来存储临时数组,空间开销较大。
1.6 示意图
假设我们有一个数组 [38, 27, 43, 3, 9, 82, 10]
,下面是归并排序的详细示意图:
分解阶段
原始数组: [38, 27, 43, 3, 9, 82, 10]/ \[38, 27, 43, 3] [9, 82, 10]/ \ / \[38, 27] [43, 3] [9, 82] [10]/ \ / \ / \
[38] [27] [43] [3] [9] [82]
合并阶段
合并 [38] 和 [27] -> [27, 38]
合并 [43] 和 [3] -> [3, 43]
合并 [9] 和 [82] -> [9, 82]合并 [27, 38] 和 [3, 43] -> [3, 27, 38, 43]
合并 [9, 82] 和 [10] -> [9, 10, 82]合并 [3, 27, 38, 43] 和 [9, 10, 82] -> [3, 9, 10, 27, 38, 43, 82]
通过不断地分解和合并,最终得到一个有序的数组。这个过程可以清晰地展示归并排序的分治思想。
2. 非比较排序 *
再此我们了解一下
非比较排序是一类不通过直接比较元素大小来确定元素顺序的排序算法,在某些特定场景下,它们的时间复杂度可以优于基于比较的排序算法(如快速排序、归并排序等,其最优时间复杂度为 O ( n l o g n ) O(n log n) O(nlogn))。下面详细介绍几种常见的非比较排序算法。
2.1 计数排序(Counting Sort)
原理
计数排序的核心思想是统计每个元素出现的次数,借助额外数组记录每个元素在序列中出现的频次,再依据统计结果将元素有序地放回原数组。该算法适用于整数序列,且元素取值范围相对较小的情况。
步骤
- 找出最大值和最小值:遍历数组,找出其中的最大值
max
和最小值min
。 - 统计元素出现次数:创建一个长度为
max - min + 1
的计数数组count
,统计每个元素出现的次数。 - 计算累计次数:对计数数组
count
进行累加操作,使得count[i]
表示小于等于i + min
的元素的个数。 - 排序元素:根据累计次数数组,将元素依次放入结果数组中。
代码实现
#include <iostream>
#include <vector>
#include <algorithm>std::vector<int> counting_sort(const std::vector<int>& arr) {if (arr.empty()) {return arr;}// 找出最大值和最小值int min_val = *std::min_element(arr.begin(), arr.end());int max_val = *std::max_element(arr.begin(), arr.end());// 计数数组std::vector<int> count(max_val - min_val + 1, 0);// 统计元素出现次数for (int num : arr) {count[num - min_val]++;}std::vector<int> result;// 根据计数数组重构排序后的数组for (int i = 0; i < count.size(); ++i) {for (int j = 0; j < count[i]; ++j) {result.push_back(i + min_val);}}return result;
}
复杂度分析
- 时间复杂度: O ( n + k ) O(n + k) O(n+k),其中
n
是数组的长度,k
是数组中元素的取值范围。 - 空间复杂度: O ( k ) O(k) O(k),主要用于计数数组。
2.2 桶排序(Bucket Sort)
原理
桶排序的基本思想是将数组元素分配到多个桶中,每个桶再分别进行排序(可以使用其他排序算法,如插入排序),最后将各个桶中的元素依次合并起来。它适用于数据均匀分布的情况。
步骤
- 确定桶的数量和范围:根据数组的最大值和最小值,确定桶的数量和每个桶的范围。
- 分配元素到桶中:遍历数组,将每个元素放入对应的桶中。
- 对每个桶进行排序:对每个桶中的元素使用其他排序算法进行排序。
- 合并桶中的元素:将各个桶中的元素依次合并起来,得到最终的排序结果。
代码实现
#include <iostream>
#include <vector>
#include <algorithm>std::vector<double> bucket_sort(const std::vector<double>& arr) {if (arr.empty()) {return arr;}// 确定桶的数量int num_buckets = 10;// 初始化桶std::vector<std::vector<double>> buckets(num_buckets);// 找出最大值和最小值double min_val = *std::min_element(arr.begin(), arr.end());double max_val = *std::max_element(arr.begin(), arr.end());// 计算每个桶的范围double bucket_range = (max_val - min_val) / num_buckets;// 分配元素到桶中for (double num : arr) {int index = (bucket_range != 0) ? static_cast<int>((num - min_val) / bucket_range) : 0;if (index >= num_buckets) {index = num_buckets - 1;}buckets[index].push_back(num);}std::vector<double> result;// 对每个桶进行排序并合并for (auto& bucket : buckets) {std::sort(bucket.begin(), bucket.end());result.insert(result.end(), bucket.begin(), bucket.end());}return result;
}
复杂度分析
- 时间复杂度:平均情况下为 O ( n + k ) O(n + k) O(n+k),其中
n
是数组的长度,k
是桶的数量。最坏情况下为 O ( n 2 ) O(n^2) O(n2)。 - 空间复杂度: O ( n + k ) O(n + k) O(n+k),主要用于存储桶和排序结果。
2.3 基数排序(Radix Sort)
原理
基数排序是一种多关键字排序算法,它通过多次对元素的每一位进行排序,从最低位到最高位,逐步确定元素的顺序。该算法适用于整数排序。
步骤
- 确定最大位数:找出数组中最大的元素,确定其位数。
- 按位排序:从最低位开始,依次对每一位进行计数排序。
代码实现
#include <iostream>
#include <vector>void counting_sort_for_radix(std::vector<int>& arr, int exp) {int n = arr.size();std::vector<int> output(n);std::vector<int> count(10, 0);// 统计每个位上的元素出现次数for (int i = 0; i < n; ++i) {int index = (arr[i] / exp) % 10;count[index]++;}// 计算累计次数for (int i = 1; i < 10; ++i) {count[i] += count[i - 1];}// 排序元素for (int i = n - 1; i >= 0; --i) {int index = (arr[i] / exp) % 10;output[count[index] - 1] = arr[i];count[index]--;}// 将排序结果复制回原数组for (int i = 0; i < n; ++i) {arr[i] = output[i];}
}std::vector<int> radix_sort(std::vector<int> arr) {if (arr.empty()) {return arr;}// 找出最大元素int max_num = *std::max_element(arr.begin(), arr.end());// 确定最大位数for (int exp = 1; max_num / exp > 0; exp *= 10) {counting_sort_for_radix(arr, exp);}return arr;
}
复杂度分析
- 时间复杂度: O ( d ( n + k ) ) O(d(n + k)) O(d(n+k)),其中
n
是数组的长度,k
是基数(通常为 10),d
是最大元素的位数。 - 空间复杂度: O ( n + k ) O(n + k) O(n+k),主要用于计数数组和输出数组。
总结
非比较排序算法在特定场景下具有较高的效率,但它们通常对数据有一定的要求,如数据范围、数据分布等。在实际应用中,需要根据数据的特点选择合适的排序算法。
3. 排序算法复杂度及稳定性分析
常见排序算法的时间复杂度、空间复杂度及稳定性分析如下:
3.1 比较排序
- 冒泡排序
- 时间复杂度:
- 最好情况为 O ( n ) O(n) O(n),当数组已经有序时,只需进行一次遍历,比较 n − 1 n - 1 n−1 次,无需交换元素。
- 最坏情况为 O ( n 2 ) O(n^2) O(n2),当数组逆序时,需要进行 n − 1 n - 1 n−1 趟排序,第 i i i 趟需要比较 n − i n - i n−i 次,总共比较次数为 ∑ i = 1 n − 1 ( n − i ) = n ( n − 1 ) 2 \sum_{i = 1}^{n - 1}(n - i)=\frac{n(n - 1)}{2} ∑i=1n−1(n−i)=2n(n−1),交换次数也为 O ( n 2 ) O(n^2) O(n2)。
- 平均时间复杂度为 O ( n 2 ) O(n^2) O(n2)。
- 空间复杂度: O ( 1 ) O(1) O(1),因为只需常数级别的额外空间来进行元素交换。
- 稳定性:稳定。在比较相邻元素时,如果相等则不交换,相同元素的相对顺序不会改变。
- 时间复杂度:
- 插入排序
- 时间复杂度:
- 最好情况为 O ( n ) O(n) O(n),数组有序时,每次插入都只需比较一次,无需移动元素。
- 最坏情况为 O ( n 2 ) O(n^2) O(n2),数组逆序时,第 i i i 个元素插入时需要比较 i i i 次,移动 i i i 个位置,总共比较和移动次数都为 ∑ i = 1 n − 1 i = n ( n − 1 ) 2 \sum_{i = 1}^{n - 1}i=\frac{n(n - 1)}{2} ∑i=1n−1i=2n(n−1)。
- 平均时间复杂度为 O ( n 2 ) O(n^2) O(n2)。
- 空间复杂度: O ( 1 ) O(1) O(1),仅需要常数级别的额外空间。
- 稳定性:稳定。在插入元素时,会将相同元素保持原来的相对顺序。
- 时间复杂度:
- 选择排序
- 时间复杂度:
- 无论最好、最坏还是平均情况,时间复杂度都是 O ( n 2 ) O(n^2) O(n2)。因为每一趟都需要遍历未排序部分找到最小(或最大)元素,总共需要 n − 1 n - 1 n−1 趟,比较次数为 ∑ i = 1 n − 1 ( n − i ) = n ( n − 1 ) 2 \sum_{i = 1}^{n - 1}(n - i)=\frac{n(n - 1)}{2} ∑i=1n−1(n−i)=2n(n−1),交换次数为 n − 1 n - 1 n−1 次。
- 空间复杂度: O ( 1 ) O(1) O(1),只需常数级别的额外空间用于交换元素。
- 稳定性:不稳定。例如序列
5,8,5,2,9
,选择最小元素2
与第一个5
交换后,两个5
的相对顺序发生了改变。
- 时间复杂度:
- 归并排序
- 时间复杂度:
- 无论最好、最坏还是平均情况,时间复杂度都是 O ( n l o g n ) O(nlogn) O(nlogn)。归并排序将数组不断分成两半,直到每个子数组只有一个元素,然后再将子数组合并,合并操作的时间复杂度为 O ( n ) O(n) O(n),而划分的层数为 l o g n logn logn,所以总的时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)。
- 空间复杂度: O ( n ) O(n) O(n),需要额外的 O ( n ) O(n) O(n) 空间来存储临时数组用于合并操作。
- 稳定性:稳定。在合并过程中,如果两个子数组中有相同的元素,会先将前面子数组中的元素放入临时数组,保证相同元素的相对顺序不变。
- 时间复杂度:
- 快速排序
- 时间复杂度:
- 最好情况为 O ( n l o g n ) O(nlogn) O(nlogn),每次划分都能将数组均匀分成两部分,划分次数为 l o g n logn logn,每次划分需要 O ( n ) O(n) O(n) 的时间,所以时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)。
- 最坏情况为 O ( n 2 ) O(n^2) O(n2),当数组已经有序或逆序时,每次划分只能将数组分成一个元素和 n − 1 n - 1 n−1 个元素的两部分,需要进行 n − 1 n - 1 n−1 次划分,每次划分需要 O ( n ) O(n) O(n) 的时间,所以时间复杂度为 O ( n 2 ) O(n^2) O(n2)。
- 平均时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)。
- 空间复杂度:
- 最好情况为 O ( l o g n ) O(logn) O(logn),因为只需 O ( l o g n ) O(logn) O(logn) 的栈空间来存储递归调用的信息。
- 最坏情况为 O ( n ) O(n) O(n),当出现最坏的划分情况时,递归深度达到 n n n。
- 稳定性:不稳定。例如序列
5,8,5,2,9
,以第一个5
为枢轴进行划分时,两个5
的相对顺序可能会改变。
- 时间复杂度:
- 堆排序
- 时间复杂度:
- 无论最好、最坏还是平均情况,时间复杂度都是 O ( n l o g n ) O(nlogn) O(nlogn)。建堆的时间复杂度为 O ( n ) O(n) O(n),然后进行 n − 1 n - 1 n−1 次调整堆的操作,每次调整堆的时间复杂度为 O ( l o g n ) O(logn) O(logn),所以总的时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)。
- 空间复杂度: O ( 1 ) O(1) O(1),只需要常数级别的额外空间。
- 稳定性:不稳定。在调整堆的过程中,相同元素的相对顺序可能会改变。
- 时间复杂度:
3.2 非比较排序
- 计数排序
- 时间复杂度: O ( n + k ) O(n + k) O(n+k),其中 n n n 是数组元素个数, k k k 是数组中元素的取值范围。需要遍历数组两次,第一次统计每个元素出现的次数,第二次根据统计结果将元素放回原数组。
- 空间复杂度: O ( k ) O(k) O(k),需要额外的空间来存储每个元素的出现次数。
- 稳定性:稳定。在将元素放回原数组时,相同元素会按照原来的顺序依次放入。
- 桶排序
- 时间复杂度:
- 平均情况为 O ( n + k ) O(n + k) O(n+k),其中 n n n 是数组元素个数, k k k 是桶的个数。将元素分配到桶中以及对每个桶内的元素进行排序(通常采用简单排序算法)的时间复杂度为 O ( n ) O(n) O(n),而遍历桶的时间复杂度为 O ( k ) O(k) O(k)。
- 最坏情况为 O ( n 2 ) O(n^2) O(n2),当所有元素都分配到同一个桶中时,退化为简单排序算法。
- 空间复杂度: O ( n + k ) O(n + k) O(n+k),需要额外的空间来存储桶和桶内的元素。
- 稳定性:稳定。如果桶内采用稳定的排序算法,那么桶排序就是稳定的。
- 时间复杂度:
- 基数排序
- 时间复杂度: O ( d ( n + k ) ) O(d(n + k)) O(d(n+k)),其中 d d d 是数字的位数, n n n 是数组元素个数, k k k 是基数(通常为 10)。需要对每个位数进行 d d d 次排序,每次排序的时间复杂度为 O ( n + k ) O(n + k) O(n+k)。
- 空间复杂度: O ( n + k ) O(n + k) O(n+k),需要额外的空间来存储桶和临时数组。
- 稳定性:稳定。在按位排序的过程中,相同元素的相对顺序不会改变。
当你看到这里的时候,我相信你对排序已经有了较为明确的认知了,缺的只是如何更好的去应用了,那么咱们C++再见咯…
请大家看我超喜欢拍的一张海边日出!!!
相关文章:
归并排序排序总结
1. 归并排序 1.1 基本思想 归并排序(Merge Sort)是采用分治法(Divide and Conquer)的一个非常典型的应用。它的基本思想是将一个数组分成两个子数组,分别对这两个子数组进行排序,然后将排好序的子数组合并…...
面试手撕——快速排序
思路 partition方法将整个区间分为两部分,一部分比pivot小,一部分比pivot大, i表示,小于等于pivot的下标,j表示当前遍历到哪一个元素了,如果发现当前元素j小于等于pivot,i,在i1的位…...
大模型微调之LLaMA-Factory 系列教程大纲
LLaMA-Factory 系列教程大纲 一、基础入门篇:环境搭建与核心功能解析 环境部署与框架特性 硬件要求: 单机训练:推荐 24GB 显存 GPU(如 RTX 4090),支持 7B-32B 模型 LoRA 微调。分布式训练:2 块…...
26考研 | 王道 | 计算机网络 | 第一章 计算机网络的体系结构
26考研 | 王道 | 第一章 计算机网络的体系结构 文章目录 26考研 | 王道 | 第一章 计算机网络的体系结构1.1 计算机网络概述1.计算机网络的概念2.计算机网络的组成**从组成部分看****从工作方式看****从逻辑功能看** 3.计算机网络的功能4.电路交换、报文交换、分组交换1. 电路交…...
CentosLinux系统crontab发现执行删除命令失效解决方法
权限或安全策略限制 可能场景: ### 目录权限冲突: 你的目录权限为 drwxr-xr-x(属主 mssql),但 cron 任务以 root 执行。 风险点:若目录内文件属主为 mssql 且权限为 700&…...
UniApp页面路由详解
一、路由系统概述 1.1 路由机制原理 UniApp基于Vue.js实现了一套跨平台的路由管理系统,其核心原理是通过维护页面栈来管理应用内不同页面之间的跳转关系。在小程序端,UniApp的路由系统会映射到对应平台的原生导航机制;在H5端则基于HTML5 Hi…...
探索无人机模拟环境的多元景象及AI拓展
无人驾驶飞行器(UAVs)在各行各业的迅速普及,从农业和检测到空中操作和人机交互等令人兴奋的前沿领域,都引发了一个关键需求:强大而逼真的模拟环境。直接在物理硬件上测试尖端算法存在固有的风险——成本高昂的坠机、中…...
Java后端开发day39--方法引用
(以下内容全部来自上述课程) 1.1 含义 把已经有的方法拿过来用,当作函数式接口中抽象方法的方法体。 已经有的方法:可以是Java自己写的,也可以是第三方的。 示例语句: ::是方法引…...
C# 14 field keyword:属性简化新利器
引言 在 C# 的不断发展历程中,每一个新版本都带来了令人期待的新特性,而 C# 14 中的 field keyword 无疑是其中一颗璀璨的明星 。对于广大 C# 开发者来说,属性的使用频率极高,而 field keyword 的出现,为我们简化属性…...
破茧成蝶:一家传统制造企业的年轻化转型之路
2004 年,在长三角的轻工业重镇杭集,一家专注于植毛机器设备研发的小工厂悄然诞生。那时,它以 “齿轮与钢铁” 为语言,为全国近千家牙刷生产企业提供核心装备,用机械臂的精准律动,编织着传统制造业的经纬。然…...
【语法】C++的继承
目录 继承基本语法: protected访问限定符: 子类和父类之间的赋值兼容规则: 重定义(隐藏): 继承中的友元/继承中的静态成员: 子类中的默认成员函数 构造函数/拷贝构造函数: 赋值重载函数ÿ…...
如何知道Ubuntu的端口是否被占用,被那个进程占用?如何终止进程
要检查Ubuntu系统中某个端口,比如5034,是否被占用及终止对应进程,请按以下步骤操作: 1. 检查端口占用情况 方法一:使用 lsof 命令 sudo lsof -i :5034输出结果会显示占用该端口的进程名、PID等信息。 方法二&#x…...
verdi使用tcl脚本批量添加波形
打开verdi console功能 在verdi的tools 里使能工具中的console功能; 在console执行tcl脚本 set cell_list { ts_0_lockup_latchn_clkc45_intno45811_i u_rst_scan_n_tp/u_scan_crl_reg/u_cell u_scan_crl_reg/u_cell u_scan_crl_reg/u_cell } ## specify the waveform window…...
【行业特化篇3】制造业简历优化指南:技术参数与标准化流程的关键词植入艺术
写在最前 作为一个中古程序猿,我有很多自己想做的事情,比如埋头苦干手搓一个低代码数据库设计平台(目前只针对写java的朋友),比如很喜欢帮身边的朋友看看简历,讲讲面试技巧,毕竟工作这么多年,也做到过高管,有很多面人经历,意见还算有用,大家基本都能拿到想要的offe…...
oracle怎样通过固化较优执行计划来优化慢sql
一 问题描述 有次生产环境cpu使用率增高,ADDM报告提示某条sql比较耗费cpu: 提示: 在分析期间, 此 SQL 语句至少利用了 6 个不同的执行计划 #查看该sql都有哪些执行计划 SELECT * FROM table(DBMS_XPLAN.DISPLAY_AWR(sqlid值)); 我手动执…...
【无标题】好用的远程链接插件
现在在做后端开发有的时候需要链接到远程服务器,有很多插件看不到整体的目录结构 推荐 trae的 ssh Client 有很清晰的目录结构...
Plant Simulation MultiPortalCrane Store 小案例
一个天车从库区移动商品到指定地点的案例 库区商品:库区上随机位置摆放商品,在源上绑定方法(应该也可以直接在库区上生成,我这里是使用源可以改变生成多少个商品) // 源的self.OnExit var Store : object : 存储 var …...
MyBatis 使用 POJO 参数动态查询教程
项目结构概览(基于图片描述): mybatis02 ├─ src/main/java │ └─ cn.cjxy │ ├─ domain # 实体类(如 Emp.java) │ ├─ mapper # Mapper 接口(如 EmpMapper.java) │…...
【MCP Node.js SDK 全栈进阶指南】高级篇(5):MCP之微服务架构
引言 在软件架构中,微服务模式已成为构建可扩展系统的主流方案。 将MCP与微服务架构结合,能够为AI驱动的应用带来显著优势。 本文将探讨如何在微服务环境中集成和部署MCP服务,以及如何利用云原生技术实现高可用、高性能的MCP应用。 目录 MCP在微服务中的角色服务网格集成容…...
UBUS 通信接口的使用——添加一个object对象(ubus call)
1,引入 ubus提供了一种多进程通信的机制。存在一个守护进程ubusd,所以进程都注册到ubusd,ubusd进行消息的接收、分发管理。 ubus对多线程支持的不好,例如在多个线程中去请求同一个服务,就有可能出现不可预知的结果。 …...
强化学习贝尔曼方程推导
引言 强化学习中贝尔曼方程的重要性就不说了,本文利用高中生都能看懂的数学知识推导贝尔曼方程。 回报 折扣回报 G t G_t Gt的定义为: G t R t 1 γ R t 2 γ 2 R t 3 ⋯ ∑ k 0 ∞ γ k R t k 1 (1) G_t R_{t1} \gamma R_{t2} \gamm…...
【MCP Node.js SDK 全栈进阶指南】高级篇(2):MCP高性能服务优化
前言 随着MCP应用规模的扩大和用户量的增加,性能优化成为系统稳定运行的关键因素。高性能的MCP服务不仅能提供更好的用户体验,还能降低运营成本,提高系统的可扩展性。本文将深入探讨MCP TypeScript-SDK的性能优化策略,帮助开发者构建高效、稳定的MCP服务。 1. 性能瓶颈识…...
图片识别为提示词,背景信息提取 -从头设计数字生命第7课, demucs——仙盟创梦IDE
1. 图像内容理解与标注 用途:在大规模图像数据集的整理和标注工作中,通过特定提示词可引导图片识别系统更准确地提取图像中的背景信息,并进行标注。例如在医学图像库标注中,使用 “疾病相关背景特征” 作为提示词,系统…...
域对齐是什么
域对齐(Domain Alignment)是在机器学习和计算机视觉等领域中常用的技术 定义 域对齐旨在将不同域(Domain)的数据映射到一个共同的特征空间中,使得来自不同域的数据在该空间中具有相似的分布。这里的“域”可以指代不…...
opencv 直方图均衡化
直方图均衡化 1. 啥叫直方图2. 绘制直方图3. 直方图均衡化3.1 自适应直方图均衡化(cv2.equalizeHist())3.2 对比度受限的自适应直方图均衡化(cv2.createCLAHE()) 1. 啥叫直方图 直方图是对数据进行统计的一种方法,并且将统计值组织到一系列实…...
JDK 8 函数式接口全集
JDK 8 函数式接口全集 函数式接口如何定义关于注解 FunctionalInterface 函数式接口的分类与简单使用生产型接口 Supplier使用 消费型接口 Consumer使用 函数型接口(Function)实例(合并字符串) 断言型接口(Predicate)…...
网站防护无惧DDoS攻击:2025年实战指南
在数字化时代,DDoS攻击已成为企业生存的“生死线”。2024年全球日均攻击峰值突破5.4Tbps(Cloudflare数据),电商、金融行业更是重灾区。本文将结合最新技术趋势和实战案例,为你提供一套低成本、高可靠的防御方案。 一、…...
【AI论文】BitNet v2:针对1位LLM的原生4位激活和哈达玛变换
摘要:激活异常值阻碍了1位大型语言模型(LLM)的有效部署,这使得低比特宽度的量化变得复杂。 我们介绍了BitNet v2,这是一个新的框架,支持1位LLM的原生4位激活量化。 为了解决注意力和前馈网络激活中的异常值…...
windows 使用 FFmpeg 放大视频原声
问题:原视频声音太小,就算把视频音量调到最大,声音也听不太清 一、下载 下载地址:Download FFmpeg 根据需要选择合适版本下载解压,如浏览器下载速度慢,可使用迅雷下载 二、配置环境变量 1.把解压的文件放…...
RHCE第七章:SElinux
一、SElinux SELinux 是一套安全策略系统 1.作用: (1)SELinux 域限制:对服务程序的功能进行限制,以确保服务程序做不了出格的事 (2)SELinux 安全上下文:对文件资源的访问限制&am…...
一文简单记录打通K8s+Kibana流程如何启动(Windows下的Docker版本)
为ES和Kibana组建Docker网络 docker network create elastic下载8.18.0版本镜像Es并启动 docker run --name es-node01 --net elastic -p 9200:9200 -p 9300:9300 -t docker.elastic.co/elasticsearch/elasticsearch:8.18.0启动Kibana(简单一些直接咯和ES对应版本…...
【系统参数合法性校验】spring-boot-starter-validation
JSR303校验 统一校验的需求 前端请求后端接口传输参数,是在controller中校验还是在Service中校验? 答案是都需要校验,只是分工不同。 Contoller中校验请求参数的合法性,包括:必填项校验,数据格式校验&…...
蓝桥杯 10. 凯撒加密
凯撒加密 原题目链接 题目描述 给定一个单词,请使用凯撒密码将这个单词加密。 凯撒密码是一种替换加密的技术,单词中的所有字母都在字母表上向后偏移 3 位后被替换成密文。 即: a → db → e⋯w → zx → ay → bz → c 输入描述 输入…...
Discord多账号注册登录:如何同时管理多个账户?
Discord是许多人、特别是游戏玩家和社区管理者的重要沟通工具。随着用户需求的增长,越来越多的人开始在Discord上注册多个账号进行管理。例如,个人和工作账号的区分,多个游戏社区的参与,或者通过不同的身份进行更灵活的社交互动。…...
Harbor默认Redis与Notary组件弱口令漏洞分析与修复指南
一、 背景 某资源池控制面和运行面生产环境部署的harbor被漏扫出弱口令需要进行整改,主要涉及 default、server、signer用户存在弱口令。 二、 分析与处理 首先需求确认这三个用户是harbor那个组件使用,最好确认的是default这个用户,它是r…...
【Prometheus-Postgres Exporter安装配置指南,开机自启】
目录 内容概述 一、安装步骤1. 安装 PostgreSQL Exporter2. 创建 PostgreSQL 监控用户3. 配置 Systemd 服务4. 启动并验证服务5. 集成到 Prometheus 内容概述 本教程详细指导如何安装 PostgreSQL Exporter(版本 0.15.0),包括: 软…...
leetcode:3005. 最大频率元素计数(python3解法)
难度:简单 给你一个由 正整数 组成的数组 nums 。 返回数组 nums 中所有具有 最大 频率的元素的 总频率 。 元素的 频率 是指该元素在数组中出现的次数。 示例 1: 输入:nums [1,2,2,3,1,4] 输出:4 解释:元素 1 和 2 的…...
论文导读 - 基于特征融合的电子鼻多任务深度学习模型研究
基于特征融合的电子鼻多任务深度学习模型研究 原论文地址:https://www.sciencedirect.com/science/article/pii/S0925400524009365 引用此论文(GB/T 7714-2015): NI W, WANG T, WU Y, et al. Multi-task deep learning model f…...
VSCode突然连接不上服务器(已解决)
可恶,不知道昨天还好好的VSCode还可以连接到服务器,今天打开就连接不上了,搜了一圈很多都说是服务端的vscode-server这个文件里面保存的commitID与当前我们VSCode上的ID不一致导致连接失败(据说是因为VSCode自动更新导致的&#x…...
解决Ollama run qwen3:32b: Error: unable to load model问题
问题描述 在尝试使用Ollama部署Qwen3模型时,许多用户遇到了以下错误: ollama run qwen3:32b Error: unable to load model: /Users/xxxx/.ollama/models/blobs/sha256-3291abe70f16ee9682de7bfae08db5373ea9d6497e614aaad63340ad421d6312这个错误通常会…...
C++ 单例对象自动释放(保姆级讲解)
目录 单例对象自动释放(重点*) 方式一:利用另一个对象的生命周期管理资源 方式二:嵌套类 静态对象(重点) 方式三:atexit destroy 方式四:atexit pthread_once 单例对象自动释…...
李录谈卖出股票的时机:价值投资的动态决策框架
作为最贴近芒格与巴菲特投资理念的中国投资人,李录对卖出时机的思考融合了价值投资的核心逻辑与实战经验。通过其在哥伦比亚大学的多场演讲及访谈(主要集中于2006年、2013年及后续公开内容),我们可以将其观点归纳为以下五个维度&a…...
Docker的简单使用(不全)
Docker Hello World Docker 允许在容器内运行应用程序,使用docker run命令来在容器内运行一个应用程序 输出Hello World runoobrunoob:~$ docker run ubuntu:15.10 /bin/echo "Hello world"Hello world docker:Docker的二进制执行文件 run…...
A2A与MCP:理解它们的区别以及何时使用
随着AI不断深入到商业工作流中,多个AI代理(Agent)之间的无缝协作成为了一个主要挑战。 为了解决这个问题,Google Cloud推出了一种名为Agent2Agent(A2A)的开放协议,旨在使不同平台和系统中的AI代…...
AI Agent开源技术栈
构建和编排Agent的框架 如果您是从头开始构建,请从这里开始。这些工具可以帮助您构建Agent的逻辑——做什么、何时做以及如何处理工具。您可以将其视为将原始语言模型转化为更自主的模型的核心大脑。 2. 计算机和浏览器的使用 一旦你的Agent能够规划,…...
判断用户选择的Excel单元格区域是否跨页?
VBA应用程序开发过程中,经常需要处理用户选中的单元格区域,有的应用场景中,需要限制用户选中区域位于同一页中(以打印预览显示的分页划分),但是VBA对象模型中并没有提供相应的接口,用于快速查询…...
驱动开发硬核特训 · Day 24(上篇):走进Linux内核时钟子系统 —— 硬件基础全解析
一、前言 在 SoC(System on Chip)设计中,“时钟(Clock)”不仅是信号同步的基石,也是各个模块协调运作的前提。没有合理的时钟体系,CPU无法运行,外设无法通信,存储器无法…...
【GPU 微架构技术】Pending Request Table(PRT)技术详解
PRT(Pending Request Table)是 GPU 中用于管理 未完成内存请求(outstanding memory requests)的一种硬件结构,旨在高效处理大规模并行线程的内存访问需求。与传统的 MSHR(Miss Status Handling Registers&a…...
角度(degrees)和弧度(radians)转换关系
目录 1.从角度转换到弧度: 2.从弧度转换到角度: 示例 将90度转换为弧度: 将π/3弧度转换为角度: 角度(degrees)和弧度(radians)之间的转换关系可以通过以下公式来实现ÿ…...
【大语言模型DeepSeek+ChatGPT+GIS+Python】AI大语言模型驱动的地质灾害全流程智能防治:风险评估、易发性分析与灾后重建多技术融合应用
地质灾害是指全球地壳自然地质演化过程中,由于地球内动力、外动力或者人为地质动力作用下导致的自然地质和人类的自然灾害突发事件。在降水、地震等自然诱因的作用下,地质灾害在全球范围内频繁发生。我国不仅常见滑坡灾害,还包括崩塌、泥石流…...