解码数据有序之道——常见排序算法总结
本文整理了常见的排序算法,采用c++编码,并对其时间复杂度作以了分析。
1. 冒泡排序(Bubble Sort)
实现思路:
- 从数组的第一个元素开始,依次比较相邻的两个元素。
- 如果当前元素大于下一个元素,则交换它们的位置。
- 经过一轮比较,最大的元素会“浮”到数组的末尾。
- 重复这个过程,每一轮都把未排序部分的最大元素移到正确位置,总共需要进行
n - 1轮(n为数组元素个数)。
代码实现:
#include <iostream>
#include <vector>
using namespace std;void bubbleSort(vector<int>& arr) {int n = arr.size();for (int i = 0; i < n - 1; ++i) {for (int j = 0; j < n - i - 1; ++j) {if (arr[j] > arr[j + 1]) {swap(arr[j], arr[j + 1]);}}}
}
时间复杂度:
- 最好情况:数组已经有序,只需进行一轮比较,没有元素交换,时间复杂度为 O ( n ) O(n) O(n)。
- 最坏情况:数组完全逆序,需要进行
n - 1轮比较,每轮比较n - i - 1次(i为当前轮数),时间复杂度为 O ( n 2 ) O(n^2) O(n2)。 - 平均情况:时间复杂度也是 O ( n 2 ) O(n^2) O(n2)。
2. 选择排序(Selection Sort)
实现思路:
- 首先在未排序的序列中找到最小(大)元素,存放到排序序列的起始位置。
- 然后,再从剩余未排序元素中继续寻找最小(大)元素,放到已排序序列的末尾。
- 重复这个过程,直到所有元素均排序完毕,一共需要进行
n - 1次选择操作(n为数组元素个数)。
代码实现:
#include <iostream>
#include <vector>
using namespace std;void selectionSort(vector<int>& arr) {int n = arr.size();for (int i = 0; i < n - 1; ++i) {int minIndex = i;for (int j = i + 1; j < n; ++j) {if (arr[j] < arr[minIndex]) {minIndex = j;}}swap(arr[i], arr[minIndex]);}
}
时间复杂度:
- 无论数组初始状态如何,都需要进行
n - 1轮选择操作,每轮都要遍历剩余未排序元素,所以最好、最坏、平均情况的时间复杂度都是 O ( n 2 ) O(n^2) O(n2)。
3. 插入排序(Insertion Sort)
实现思路:
- 将数组分为已排序和未排序两部分,初始时已排序部分只有第一个元素。
- 取未排序部分的第一个元素,将其插入到已排序部分的合适位置,使得已排序部分依然有序。
- 重复这个过程,直到未排序部分为空。
代码实现:
#include <iostream>
#include <vector>
using namespace std;void insertionSort(vector<int>& arr) {int n = arr.size();for (int i = 1; i < n; ++i) {int key = arr[i];int j = i - 1;while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];j--;}arr[j + 1] = key;}
}
时间复杂度:
- 最好情况:数组已经有序,每次插入操作只需比较一次,时间复杂度为 O ( n ) O(n) O(n)。
- 最坏情况:数组完全逆序,每次插入都要和已排序部分的所有元素比较并移动,时间复杂度为 O ( n 2 ) O(n^2) O(n2)。
- 平均情况:时间复杂度为 O ( n 2 ) O(n^2) O(n2)。
4.希尔排序(Shell Sort)
实现思路
- 希尔排序是对插入排序的改进,它的基本思想是先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序。
- 首先选择一个合适的间隔(称为“步长”或“增量”,通常初始化为数组长度的一半,然后每次缩小一半,直到步长为1)。
- 按照选定的步长,对相隔该步长的元素组成的子序列进行插入排序,例如步长为
gap时,会把数组分成多个子序列,分别是arr[0], arr[gap], arr[2 * gap],...、arr[1], arr[1 + gap], arr[1 + 2 * gap],...等这些子序列,对每个子序列进行插入排序操作。 - 随着步长逐渐减小,子序列的元素个数逐渐增多,当步长最终减为1时,整个数组就相当于进行了一次普通的插入排序,但此时由于前面以较大步长进行了预排序,元素已经相对更接近最终位置,所以最后一次插入排序会比直接对原始数组进行插入排序效率更高。
代码实现
#include <iostream>
#include <vector>
using namespace std;void shellSort(vector<int>& arr) {int n = arr.size();for (int gap = n / 2; gap > 0; gap /= 2) {for (int i = gap; i < n; i++) {int temp = arr[i];int j;for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {arr[j] = arr[j - gap];}arr[j] = temp;}}
}
时间复杂度
- 希尔排序的时间复杂度与所选取的步长序列有关,它的时间复杂度分析比较复杂。
- 最好情况:当数组已经有序时,时间复杂度接近 O ( n ) O(n) O(n),因为每个子序列在插入排序时几乎不需要移动元素。
- 最坏情况:时间复杂度依赖于步长序列,不同的步长序列会导致不同的最坏情况时间复杂度,不过通常认为其最坏情况时间复杂度在 O ( n 2 ) O(n^2) O(n2) 左右,例如使用
Hibbard序列作为步长时最坏情况为 O ( n 3 / 2 ) O(n^{3/2}) O(n3/2) 等。 - 平均情况:平均时间复杂度介于 O ( n ) O(n) O(n) 和 O ( n 2 ) O(n^2) O(n2) 之间,常见的分析结果大约是 O ( n 1.3 ) O(n^{1.3}) O(n1.3) 左右。
5. 快速排序(Quick Sort)
实现思路:
- 选择一个基准元素(通常是数组的最后一个元素)。
- 通过一趟排序将数组分为两部分,左边部分的元素都小于等于基准元素,右边部分的元素都大于基准元素。
- 对左右两部分分别递归地进行快速排序,直到子数组的长度为1或者0。
代码实现:
#include <iostream>
#include <vector>
using namespace std;int partition(vector<int>& arr, int low, int high) {int pivot = arr[high];int i = low - 1;for (int j = low; j < high; ++j) {if (arr[j] <= pivot) {++i;swap(arr[i], arr[j]);}}swap(arr[i + 1], arr[high]);return i + 1;
}void quickSort(vector<int>& arr, int low, int high) {if (low < high) {int pi = partition(arr, low, high);quickSort(arr, low, pi - 1);quickSort(arr, pi + 1, high);}
}
时间复杂度:
- 最好情况:每次划分都能把数组均匀地分成两部分,时间复杂度为 O ( n log n ) O(n \log n) O(nlogn)。
- 最坏情况:数组已经有序或者逆序,每次划分只得到一个元素和剩余元素的子数组,时间复杂度为 O ( n 2 ) O(n^2) O(n2)。
- 平均情况:时间复杂度为 O ( n log n ) O(n \log n) O(nlogn)。
6. 归并排序(Merge Sort)
实现思路:
- 采用分治思想,先将数组不断地分成两半,直到每个子数组只有一个元素(这是递归分解的过程)。
- 然后将相邻的子数组合并成有序的数组,合并时比较两个子数组的元素,依次放入新的临时数组中,再将临时数组的元素复制回原数组对应位置(这是合并的过程)。
- 重复合并过程,直到整个数组有序。
代码实现:
#include <iostream>
#include <vector>
using namespace std;void merge(vector<int>& arr, int l, int m, int r) {int n1 = m - l + 1;int n2 = r - m;vector<int> L(n1), R(n2);for (int i = 0; i < n1; ++i) {L[i] = arr[l + i];}for (int j = 0; j < n2; ++j) {R[j] = arr[m + 1 + j];}int i = 0, j = 0, k = l;while (i < n1 && j < n2) {if (L[i] <= R[j]) {arr[k++] = L[i++];} else {arr[k++] = R[j++];}}while (i < n1) {arr[k++] = L[i++];}while (j < n2) {arr[k++] = R[j++];}
}void mergeSort(vector<int>& arr, int l, int r) {if (l < r) {int m = l + (r - l) / 2;mergeSort(arr, l, m);mergeSort(arr, m + 1, r);merge(arr, l, m, r);}
}
时间复杂度:
- 无论数组初始状态如何,每次划分都是 O ( 1 ) O(1) O(1) 的时间复杂度,合并操作总的时间复杂度为 O ( n ) O(n) O(n),一共要进行 log n \log n logn 层划分与合并,所以时间复杂度始终为 O ( n log n ) O(n \log n) O(nlogn)。
7. 堆排序(Heap Sort)
实现思路:
- 首先将数组构建成一个最大堆(从最后一个非叶子节点开始,对每个节点进行堆化操作,保证父节点大于等于子节点)。
- 然后把堆顶元素(最大值)与堆的最后一个元素交换,此时最大值就在正确的排序位置了,接着对剩下的元素重新进行堆化,使其再次成为最大堆。
- 重复这个过程,直到整个数组有序。
代码实现:
#include <iostream>
#include <vector>
using namespace std;void heapify(vector<int>& arr, int n, int i) {int largest = i;int l = 2 * i + 1;int r = 2 * i + 2;if (l < n && arr[l] > arr[largest]) {largest = l;}if (r < n && arr[r] > arr[largest]) {largest = r;}if (largest!= i) {swap(arr[i], arr[largest]);heapify(arr, n, largest);}
}void heapSort(vector<int>& arr) {int n = arr.size();for (int i = n / 2 - 1; i >= 0; --i) {heapify(arr, n, i);}for (int i = n - 1; i > 0; --i) {swap(arr[0], arr[i]);heapify(arr, i, 0);}
}
时间复杂度:
- 建堆过程时间复杂度为 O ( n ) O(n) O(n),每次调整堆的时间复杂度为 O ( log n ) O(\log n) O(logn),总共需要进行
n - 1次调整堆操作,所以时间复杂度为 O ( n log n ) O(n \log n) O(nlogn)。
8.基数排序
实现思路
- 基数计数与分配
- 基数排序的核心思想是根据数字的每一位来进行排序。对于一个整数数组,首先确定数字的最大位数(d)(例如对于十进制数,最大位数可能是数组中最大数的位数)。
- 从最低位(个位)开始,依次对每一位进行排序。对于每一位,创建(r)个桶(对于十进制数(r = 10),即0 - 9号桶)。
- 遍历数组中的每个元素,根据当前位的数字值将元素放入相应的桶中。例如,如果当前位是个位,数字(123)的个位是(3),则将(123)放入(3)号桶中。
- 收集与重复
- 按照桶的顺序(从(0)号桶到(r - 1)号桶)依次收集元素,将桶中的元素放回原数组,此时原数组就按照当前位进行了排序。
- 然后处理下一位,重复上述分配和收集的过程,直到处理完最高位。这样,经过(d)轮处理后,数组就完成了排序。
时间复杂度
- 平均情况
- 时间复杂度为(O(d(r + n))),其中(d)是数字的最大位数,(r)是基数(例如十进制数(r = 10)),(n)是待排序元素的个数。
- 分析如下:对于每一位(共(d)位),需要遍历(n)个元素来分配到®个桶中,这一步的时间复杂度是(O(n))。然后需要遍历®个桶来收集元素,时间复杂度是(O®)。所以每一位的处理时间复杂度是(O(n + r)),总共(d)位,所以平均时间复杂度是(O(d(n + r)))。
- 最好情况
- 当所有元素的位数都相同时,时间复杂度为(O(d(n + r))),这与平均情况相同。因为即使元素已经有序,基数排序仍然需要按照每一位进行处理。
- 最坏情况
- 时间复杂度为(O(d(n + rd)))。这种情况可能发生在所有元素的最高位都不同,并且每一位的取值范围很大(接近(r))。在这种情况下,对于每一位,都需要处理所有的桶,而桶的数量最多可以达到(rd)(例如,当所有元素的每一位都不同时)。
代码实现(对十进制整数数组进行排序)
#include <iostream>
#include <vector>
#include <algorithm>// 基数排序函数
void radixSort(std::vector<int>& arr) {// 找到数组中的最大值,确定最大位数int maxVal = *std::max_element(arr.begin(), arr.end());for (int exp = 1; maxVal / exp > 0; exp *= 10) {// 创建计数数组,用于统计每个桶中的元素个数std::vector<int> count(10, 0);// 计算每个元素在当前位上的数字,统计每个桶中的元素个数for (int i = 0; i < arr.size(); i++) {count[(arr[i] / exp) % 10]++;}// 计算计数数组的前缀和,确定每个桶中元素在输出数组中的位置for (int i = 1; i < 10; i++) {count[i] += count[i - 1];}// 创建输出数组,用于存储排序后的结果std::vector<int> output(arr.size());// 将元素放入相应的桶中,并按照顺序放入输出数组for (int i = arr.size() - 1; i >= 0; i--) {output[count[(arr[i] / exp) % 10] - 1] = arr[i];count[(arr[i] / exp) % 10]--;}// 将排序后的结果复制回原数组for (int i = 0; i < arr.size(); i++) {arr[i] = output[i];}}
}
测试程序
可用以下代码测试这些排序算法(将所要测试的代码取消注释即可,此时为测试堆排序):
int main() {vector<int> arr = { 5, 4, 3, 2, 1 };// bubbleSort(arr);// selectionSort(arr);//shellSort(arr);// insertionSort(arr);// quickSort(arr, 0, arr.size() - 1);// mergeSort(arr, 0, arr.size() - 1);// radixSort(arr);heapSort(arr);for (int num : arr) {cout << num << " ";}cout << endl;return 0;
}
各排序算法总结与比较:
| 类别 | 排序方法 | 时间复杂度 | 空间复杂度 | 稳定性 | 备注 | ||
|---|---|---|---|---|---|---|---|
| 平均情况 | 最好情况 | 最坏情况 | 辅助存储 | ||||
| 插入排序 | 直接插入 | O ( n 2 ) O(n^2) O(n2) | O ( n ) O(n) O(n) | O ( n 2 ) O(n^2) O(n2) | O ( 1 ) O(1) O(1) | 稳定 | 数据量小时较好 |
| Shell排序 | O ( n 1.3 ) O(n^{1.3}) O(n1.3) | O ( n ) O(n) O(n) | O ( n 2 ) O(n^2) O(n2) | O ( 1 ) O(1) O(1) | 不稳定 | ||
| 选择排序 | 直接选择 | O ( n 2 ) O(n^2) O(n2) | O ( n 2 ) O(n^2) O(n2) | O ( n 2 ) O(n^2) O(n2) | O ( 1 ) O(1) O(1) | 不稳定 | 数据量小时较好 |
| 堆排序 | O ( n log 2 n ) O(n\log_2 n) O(nlog2n) | O ( n log 2 n ) O(n\log_2 n) O(nlog2n) | O ( n log 2 n ) O(n\log_2 n) O(nlog2n) | O ( 1 ) O(1) O(1) | 不稳定 | 数据量大时较好 | |
| 交换排序 | 冒泡排序 | O ( n 2 ) O(n^2) O(n2) | O ( n ) O(n) O(n) | O ( n 2 ) O(n^2) O(n2) | O ( 1 ) O(1) O(1) | 稳定 | 数据量小时较好 |
| 快速排序 | O ( n log 2 n ) O(n\log_2 n) O(nlog2n) | O ( n log 2 n ) O(n\log_2 n) O(nlog2n) | O ( n 2 ) O(n^2) O(n2) | O ( log 2 n ) O(\log_2 n) O(log2n) | 不稳定 | 数据量大时较好 | |
| 归并排序 | O ( n log 2 n ) O(n\log_2 n) O(nlog2n) | O ( n log 2 n ) O(n\log_2 n) O(nlog2n) | O ( n log 2 n ) O(n\log_2 n) O(nlog2n) | O ( n ) O(n) O(n) | 稳定 | 数据量大时较好 | |
| 基数排序 | O ( d ( r + n ) ) O(d(r + n)) O(d(r+n)) | O ( d ( n + r d ) ) O(d(n + r^d)) O(d(n+rd)) | O ( d ( r + n ) ) O(d(r + n)) O(d(r+n)) | O ( r d + n ) O(r^d + n) O(rd+n) | 稳定 |
注:基数排序的复杂度中, r r r代表关键字的基数, d d d代表长度, n n n代表关键字的个数
总结
不同的排序算法在不同场景下有不同的性能表现。插入排序在数据量小且基本有序时效率较高;选择排序简单但效率相对较低;交换排序中的冒泡排序适用于数据量小的情况,快速排序在平均情况下性能很好但最坏情况较差;堆排序适用于数据量大且不需要稳定排序的情况;归并排序性能稳定但需要额外空间;基数排序适用于对整数等有特定结构数据的排序,且在数据范围有限时效率较高。在实际使用时,根据数据特点和需求选择合适的排序算法。
相关文章:
解码数据有序之道——常见排序算法总结
本文整理了常见的排序算法,采用c编码,并对其时间复杂度作以了分析。 1. 冒泡排序(Bubble Sort) 实现思路: 从数组的第一个元素开始,依次比较相邻的两个元素。如果当前元素大于下一个元素,则交…...
C语言实现图片文件的复制
在C语言中,直接处理图片文件(如JPEG、PNG等)的复制,通常涉及到文件I/O操作。这些图片文件是二进制文件,因此需要使用二进制模式读取和写入文件。 图片文件复制代码: #include <stdio.h> #include&l…...
一、windows上配置ninja环境
Ninja是Google的一名程序员推出的注重速度的构建工具,一般在Unix/Linux上的程序通过make/makefile来构建编译,而Ninja通过将编译任务并行组织,大大提高了构建速度。下面介绍了windows上配置Ninja环境。 1.下载Ninja ninja官网地址࿱…...
我们来编程 -- win11多jdk版本切换
题记 售前的酒喝到位了调研需求及文档整理出来了开发要入场了,真惨啊!年底了,手里活干的好好的,因为flyback在项目地,硬是被安排进来了拥抱变化,我呸…不得不切换系统,构建代码,一股…...
JAVA 图形界面编程 AWT篇(1)
前言 为了应对JAVA课设,小编走上了java的图形界面编程的道路,通过博客分享自己的学习历程,并进行笔记的记录。 AWT(Abstract Window Toolkit)介绍 AWT(抽象窗口工具包)是 Java 最早的图形用户界…...
C语言 字符串输入输出函数、scanf(“%[^\n]“,)可输入空格 、fgets删除换行符
字符串输入函数: scanf("%s",数组名) gets(数组名) fgets() --- 文件流输入函数 函数原型: int scanf( const char *format, ...…...
【蓝桥杯每日一题】推导部分和——带权并查集
推导部分和 2024-12-11 蓝桥杯每日一题 推导部分和 带权并查集 题目大意 对于一个长度为 ( N ) 的整数数列 A 1 , A 2 , ⋯ , A N A_1, A_2, \cdots, A_N A1,A2,⋯,AN ,小蓝想知道下标 ( l ) 到 ( r ) 的部分和 ∑ i l r A i A l A l 1 ⋯ A r \sum_{…...
Linux 磁盘满了怎么办?快速排查和清理方法
当 Linux 磁盘满了,会导致系统无法正常运行,比如无法写入文件、服务停止、甚至系统崩溃。因此,快速排查并清理磁盘空间是非常重要的。以下是详细的排查和解决步骤: 一、快速定位磁盘占用原因 1. 检查磁盘使用情况 使用 df 命令查…...
【专题】2024年中国新能源汽车用车研究报告汇总PDF洞察(附原数据表)
原文链接: https://tecdat.cn/?p38564 本年度,国家及地方政府持续发力,推出诸多政策组合拳,全力推动汽车产业向更高质量转型升级,积极鼓励消费升级,并大力推行以旧换新等惠民生、促发展举措。尤为引人注目…...
数据结构之链表笔试题详解
一:移除链表元素 我们很容易就可以想到一个解决方案:再创建一个链表,把不是val的结点拿过来尾插。 这样确实可以但是,我们每次尾插都需要遍历一遍整个链表,这样时间复杂度就变成了O(n^2), 因此我们不妨设…...
结构化的Prompt
资源库: AI 提示词-WayToAGI精选高效的AI提示词库,助力创作者和开发者解锁人工智能的潜力。通过我们的提示词和策略,优化您的AI工具使用效率,激发创意思维,提升产出质量。https://www.waytoagi.com/prompts?tag6 结构…...
【数字化】华为数字化转型架构蓝图
导读:华为的数字化转型规划团队在2016年年底基于对愿景的系统诠释,整合出了数字化转型架构蓝图。该蓝图共分为5层,旨在通过数字化转型实现客户交互方式的转变、作战方式的转变、公司各平台业务能力的数字化、服务化以及运营模式的转变。 目录…...
最新全开源IM即时通讯系统源码(PC+WEB+IOS+Android)部署指南
全开源IM(即时通讯)系统源码部署是一个复杂但系统的过程,涉及多个组件和步骤。以下是一个详细的部署指南,旨在帮助开发者或系统管理员成功部署一个全开源的IM系统,如OpenIM。 IM即时通讯系统源码准备工作 …...
go 跨平台打包
GOARCH是Go语言中的一个环境变量,用于指定目标平台的底层架构。在Go的交叉编译过程中,GOARCH决定了编译出的二进制文件将在哪种硬件架构上运行。 GOARCH的常见值 amd64:64位 x86 架构386:32位 x86 架构arm&am…...
C++ 给定字符串,然后给出开始要取的位置,返回取到的信息
3 happy new year 7 year 1 new 4 new year year error input #include <stdio.h> #include <string.h> void strmcpy(char* s, char* t, int m); int main() {int repeat, m;char t[1000], s[1000];scanf("%d", &repeat);getchar(); //吸收换行符in…...
【树莓派4B】MindSpore lite 部署demo
一个demo,mindspore lite 部署在树莓派4B ubuntu22.04中,为后续操作开个门! 环境 开发环境:wsl-ubuntu22.04分发版部署环境:树莓派4B,操作系统为ubuntu22.04mindspore lite版本:mindspore-li…...
Idea汉化插件Datagrip汉化插件
汉化插件 Chinese (Simplified) Language Pack / 中文语言包 插件地址 安装完了之后,如果还不是中文的怎么办 需要手动设置 Seetings -> Appearance & Behavior -> System Settings -> Language and Region -> Language 修改为 [ Chi…...
精彩回顾|Cocos开发者沙龙长沙站
长沙-不一样 Cocos 开发者沙龙长沙站,完全超出了我们的预期,一开始还担心没有太多人报名。最后发现,全场爆满,座无虚席。 <<< 左右滑动见更多 >>> 许多小伙伴曾反馈过,在以往的开发者沙龙回顾文章中…...
算法日记 49 day 图论(A*算法)
这算是算法的最后一篇了,原本A*之前还有一些相关的最短路径算法的,比如dijkstra的堆优化,SPFA等等,但是有些我没看懂,就不写了,用A*做个结尾。 题目:骑士的攻击 127. 骑士的攻击 (kamacoder.co…...
服务器批量清理redis keys,无法适用客户端必须直连的情况
在 Redis 中,批量清理指定模式的键(例如 memberCardData:*)可以通过多种方法来实现。需要注意的是,Redis 的命令执行是单线程的,因此对大量键进行操作时可能会阻塞服务器。以下是几种常见的方法: shell K…...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...
