七大排序 (9000字详解直接插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序)
一:排序的概念及引入
1.1 排序的概念
1.1 排序的概念
-
排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
-
稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。
- 内部排序:数据元素全部放在内存中的排序。
- 外部排序:数据元素太多不能同时放在内存中,根据排序过程的要求不能在内外存之间移动数据的排序。
1.2常见的排序算法
常见的排序算法有七种,分别是直接插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序
下面我们对这些排序进行一 一讲解。
二:插入排序
2.1 直接插入排序
直接插入排序是一种简单的插入排序法,其基本思想是:
把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。实际中我们玩扑克牌时,就用了插入排序的思想。
插入排序是一种简单直观的排序算法。它的原理是将待排序的元素逐个插入到已排序序列的适当位置,从而形成一个有序序列。
该算法的工作原理如下:
- 从第二个元素开始,将其与前面已排序的元素逐个比较,找到合适的位置插入。
- 将当前元素与前面已排序的元素进行比较,如果当前元素小于前面的元素,则将前面的元素后移一位,直到找到合适的位置。
- 插入当前元素到合适的位置后,继续比较并插入下一个元素。
- 重复上述步骤,直到所有元素都被插入到合适的位置。
动图如下:
下面是一个使用Java实现插入排序的示例代码:
public class InsertionSort {public static void insertionSort(int[] arr) {int n = arr.length;for (int i = 1; i < n; i++) {int key = arr[i]; // 当前要插入的元素int j = i - 1; // 已经排好序的元素的最后一个索引// 将比 key 大的元素向后移动while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j]; // 向后移动元素j--; // 向前遍历已经排好序的元素}// 插入 key 到合适的位置arr[j + 1] = key; // 将 key 插入到正确的位置}}public static void main(String[] args) {int[] arr = {5, 2, 8, 9, 1, 3};insertionSort(arr); // 使用插入排序算法对数组进行排序System.out.println("排序后的数组:");for (int num : arr) {System.out.print(num + " "); // 输出排序后的数组}}
}
直接插入排序的特性总结:
- 元素集合越接近有序,直接插入排序算法的时间效率越高
- 时间复杂度:O(N^2)
- 空间复杂度:O(1),它是一种稳定的排序算法
- 稳定性:稳定
2.2 希尔排序( 缩小增量排序 )
希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成多个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序。
下面是希尔排序的工作原理:
- 选择一个增量序列,增量序列由一系列整数构成,通常是递减的,最后一个增量必须为1。
- 根据选定的增量序列,将待排序的数组分割成若干个子数组,每个子数组包含相同间隔的元素。
- 对每个子数组进行插入排序,即将每个子数组的元素依次与该子数组中的其他元素进行比较和交换,使得子数组中的元素逐渐有序。
- 重复以上步骤,缩小增量,直至增量为1。
- 最后进行一次完整的插入排序,以保证数组的最终有序性。
示图如下:
希尔排序的特性总结:
- 希尔排序是对直接插入排序的优化。
- 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很
快。这样整体而言,可以达到优化的效果。 - 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的希尔排
序的时间复杂度都不固定
动图如下:
因为咋们的gap是按照Knuth提出的方式取值的,而且Knuth进行了大量的试验统计,我们暂时就按照:O(n1.25)到O(1.6 * n1.25) 来算。
下面是一个使用Java实现的希尔排序示例代码:
public class ShellSort {public static void shellSort(int[] arr) {int n = arr.length;// 初始化增量为数组长度的一半int gap = n / 2;while (gap > 0) {for (int i = gap; i < n; i++) {int temp = arr[i];int j = i;// 插入排序while (j >= gap && arr[j - gap] > temp) {arr[j] = arr[j - gap];j -= gap;}arr[j] = temp;}// 缩小增量gap /= 2;}}public static void main(String[] args) {int[] arr = {9, 5, 2, 7, 1, 3, 6, 8, 4};System.out.println("原始数组:");for (int num : arr) {System.out.print(num + " ");}System.out.println();shellSort(arr);System.out.println("排序后的数组:");for (int num : arr) {System.out.print(num + " ");}}
}
希尔排序稳定性:不稳定
三:选择排序
3.1直接选择排序
当我们需要对一个数组进行排序时,选择排序是一种简单而直观的算法。它的工作原理是选择数组中最小的元素,将它与数组的第一个元素交换位置。然后,选择剩余元素中最小的元素,将它与数组的第二个元素交换位置。以此类推,直到整个数组排序完成
动图如下:
public class SelectionSort {public static void main(String[] args) {// 创建一个整数数组int[] arr = {64, 25, 12, 22, 11};// 调用选择排序方法selectionSort(arr);// 输出排序后的数组System.out.println("排序后的数组:");for(int i=0; i < arr.length; i++){System.out.print(arr[i] + " ");}}public static void selectionSort(int[] arr) {// 获取数组长度int n = arr.length;// 遍历整个数组for (int i = 0; i < n-1; i++) {// 假设当前索引为 i 的元素是最小值int minIndex = i;// 在剩余的元素中寻找最小值的索引for (int j = i+1; j < n; j++) {// 如果找到比当前最小值还小的值,则更新最小值的索引if (arr[j] < arr[minIndex]) {minIndex = j;}}// 将最小值与当前位置交换int temp = arr[minIndex];arr[minIndex] = arr[i];arr[i] = temp;}}
}
【直接选择排序的特性总结】
- 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用
- 时间复杂度:O(N^2)
- 空间复杂度:O(1)
- 稳定性:不稳定
3.2堆排序
堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。
堆排序具体的讲解可以查看这篇文章
【堆排序的特性总结】
- 堆排序使用堆来选数,效率就高了很多。
- 时间复杂度:O(N*logN)
- 空间复杂度:O(1)
- 稳定性:不稳定
四:交换排序
4.1冒泡排序
冒泡排序是一种简单但效率较低的排序算法。它的基本思想是通过不断比较相邻的两个元素并交换位置,从而将较大(或较小)的元素逐渐“冒泡”到数组的顶部(或底部)。这个过程会不断重复,直到数组中的所有元素都按照顺序排列。
下面是一个详细注释的 Java 示例代码:
public class BubbleSort {public static void bubbleSort(int[] arr) {int n = arr.length;// 外层循环控制比较的轮数,每轮比较后,最大的元素就会被冒泡到数组末尾for (int i = 0; i < n - 1; i++) {// 内层循环用于比较相邻的元素并交换位置// 每轮结束后,当前轮数已经排序完成的元素就会排在数组的最后// 所以下一轮比较时,不需要再考虑这些元素for (int j = 0; j < n - 1 - i; j++) {// 如果当前元素比下一个元素大,就交换它们的位置if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}}public static void main(String[] args) {int[] arr = {64, 34, 25, 12, 22, 11, 90};System.out.println("原始数组:");for (int num : arr) {System.out.print(num + " ");}// 调用冒泡排序bubbleSort(arr);System.out.println("\n排序后的数组:");for (int num : arr) {System.out.print(num + " ");}}
}
动图如下:
【冒泡排序的特性总结】
- 冒泡排序是一种非常容易理解的排序
- 时间复杂度:O(N^2)
- 空间复杂度:O(1)
- 稳定性:稳定
4.2快速排序
快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。
4.2.1Hoare版
实现思路:
1: 首先,从数组的左端和右端分别设置一个指针,即i和j,以及选择一个基准值pivot。
2:通过循环,从数组的右端开始向左查找,找到第一个小于基准值的元素的下标,将该下标赋给j。然后从数组的左端开始向右查找,找到第一个大于基准值的元素的下标,将该下标赋给i。
3: 在找到两个元素的下标后,交换它们的位置,将小于基准值的元素移动到基准值的左边,大于基准值的元素移动到基准值的右边。然后继续循环,直到左指针i大于等于右指针j。
最后,将基准值放在正确的位置上,将其与左指针i所指向的元素进行交换。这样,基准值左边的元素都小于基准值,右边的元素都大于基准值。
需要注意的是:若选择最左边的数据作为key,则需要right先走;若选择最右边的数据作为key,则需要left先走
动图如下:
private static int partition(int[] array, int left, int right) {// 设置左右指针和基准值int i = left;int j = right;int pivot = array[left];// 在左指针小于右指针的条件下,进行循环while (i < j) {// 从右往左找到第一个小于基准值的元素的下标while (i < j && array[j] >= pivot) {j--;}// 从左往右找到第一个大于基准值的元素的下标while (i < j && array[i] <= pivot) {i++;}// 交换找到的两个元素的位置swap(array, i, j);}// 将基准值放在正确的位置上swap(array, i, left);// 返回基准值的下标return i;
}
4.2.2挖坑法
实现思路:
1: 首先,在函数内部定义两个指针i和j,分别指向分区的左侧和右侧。初始时,将left作为基准元素的索引,即基准元素为array[left]。
2: 然后,通过循环,不断将大于基准元素的元素移动到右侧,将小于基准元素的元素移动到左侧。具体的操作是,先从右侧开始,找到小于或等于基准元素的元素,然后将该元素移动到左侧指针i的位置。
3: 接着,从左侧开始,找到大于或等于基准元素的元素,然后将该元素移动到右侧指针j的位置。如此反复进行,直到指针i和j相遇。
4: 最后,将基准元素放置到它最终的位置上,也就是指针i的位置。这样,基准元素左侧的元素都小于或等于它,右侧的元素都大于或等于它。
5: 最后返回基准元素的索引i,用于后续的分区。
注意:若在最左边挖坑,则需要R先走;若在最右边挖坑,则需要L先走
动图如下:
private static int partition(int[] array, int left, int right) {// 设置指针i和j分别指向分区的左侧和右侧int i = left;int j = right;// 设置基准元素为分区的第一个元素int pivot = array[left];// 开始循环,直到指针i和j相遇while (i < j) {// 从右侧开始,寻找小于或等于基准元素的元素while (i < j && array[j] >= pivot) {j--;}// 找到后将该元素移动到左侧指针i的位置array[i] = array[j];// 从左侧开始,寻找大于或等于基准元素的元素while (i < j && array[i] <= pivot) {i++;}// 找到后将该元素移动到右侧指针j的位置array[j] = array[i];}// 将基准元素放置到它最终的位置上array[i] = pivot;// 返回基准元素的索引,用于后续的分区return i;
}
4.2.3前后指针
实现思路:
- 我们首先定义了两个变量
cur
和prev
,它们都指向数组的起始位置(cur = begin
,prev = begin - 1
)。 - 我们选择数组的最后一个元素作为基准元素,将其索引保存在变量
keyi
中。 - 然后我们开始遍历数组,从头到尾比较每个元素与基准元素的大小。
- 如果当前元素小于基准元素,并且
prev
不等于cur
,则将当前元素与prev
指向的元素交换位置。 - 随后,我们将
cur
向后移动一位。 - 当遍历完整个数组后,我们将基准元素与
prev
指向的元素交换位置,以确保基准元素的位置在整个数组中是正确的。 - 这样,数组被分成了两部分:左边是小于基准元素的部分,右边是大于基准元素的部分。基准元素的位置为
keyi
。 - 接下来,我们对左半部分(
begin
到keyi - 1
)和右半部分(keyi + 1
到end
)分别进行递归调用。 - 重复以上步骤,直到子数组的长度为 1 或 0,即递归终止条件。
//快速排序法 前后指针版本
void QuickSort2(int* arr, int begin, int end)
{if (begin >= end)return;int cur = begin, prev = begin - 1;int keyi = end;while (cur != keyi){if (arr[cur] < arr[keyi] && ++prev != cur){swap(&arr[cur], &arr[prev]);}++cur;}swap(&arr[++prev],&arr[keyi]);keyi = prev;//[begin,keyi -1]keyi[keyi+1,end]QuickSort2(arr, begin, keyi - 1);QuickSort2(arr, keyi + 1, end);}
快速排序优化
- 三数取中法选key (三个数中取中间的数为基准)
- 递归到小的子区间时,可以考虑使用插入排序
快速排序总结:
- 快速排序整体的综合性能和使用场景都是比较好的,所以才敢叫快速排序
- 时间复杂度:O(N*logN)
- 空间复杂度:O(logN)(特殊情况,如果数据本身有序或者逆序,那么时间复杂度为 O (N2))
- 稳定性:不稳定
时间复杂度示图:
五:归并排序
5.1 基本思想
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide andConquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 归并排序核心步骤:
动图:
归并排序总结:
- 归并的缺点在于需要O(N)的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题。
- 时间复杂度:O(N*logN)
- 空间复杂度:O(N)
- 稳定性:稳定
5.2 代码实现
public class MergeSort {// 归并排序入口函数public int[] mergeSort(int[] array) {// 特殊情况处理:当数组为空或只有一个元素时,无需排序,直接返回if (array == null || array.length <= 1) {return array;}// 调用归并排序算法进行排序mergeSort(array, 0, array.length - 1);return array;}// 归并排序递归函数private void mergeSort(int[] array, int start, int end) {// 当前排序范围只有一个元素,无需继续拆分if (start >= end) {return;}// 找到当前排序范围的中间位置int mid = start + (end - start) / 2;// 递归拆分左半部分mergeSort(array, start, mid);// 递归拆分右半部分mergeSort(array, mid + 1, end);// 合并左右两部分排序结果merge(array, start, mid, end);}// 归并两个有序数组private void merge(int[] array, int start, int mid, int end) {// 创建一个临时数组保存合并的结果int[] temp = new int[end - start + 1];int i = start; // 左半部分起始位置int j = mid + 1; // 右半部分起始位置int k = 0; // 临时数组的索引// 遍历左右两部分数组,依次取出较小的元素放入临时数组中while (i <= mid && j <= end) {if (array[i] < array[j]) {temp[k++] = array[i++];} else {temp[k++] = array[j++];}}// 处理剩余的元素while (i <= mid) {temp[k++] = array[i++];}while (j <= end) {temp[k++] = array[j++];}// 将临时数组中的元素拷贝回原数组中for (i = 0; i < temp.length; i++) {array[start + i] = temp[i];}}
}
下面对这段代码进行详细的讲解:
- 首先我们定义了一个公共类MergeSort,用于实现归并排序算法。
- mergeSort方法是入口函数,接收一个整型数组作为参数,并返回一个排序后的整型数组。在这个方法中,首先判断特殊情况,即当数组为空或只有一个元素时,无需排序,直接返回原数组;否则,调用归并排序算法进行排序。
- 归并排序的核心是递归拆分和合并两个有序数组。
- mergeSort方法是一个递归函数,接收一个整型数组array和两个整型变量start和end作为参数,表示当前排序范围的起始位置和结束位置。首先判断当前范围是否只有一个元素,如果是,则无需继续拆分;否则,找到当前范围的中间位置mid,分别递归拆分左半部分和右半部分,然后将拆分后的结果合并起来。
- merge方法用于合并两个有序数组。它接收一个整型数组array和三个整型变量start、mid和end作为参数,表示需要合并的两个有序数组在原数组中的位置。首先创建一个临时数组temp,用于保存合并的结果,长度为end-start+1。然后设置三个指针i、j和k,分别表示左半部分数组的起始位置、右半部分数组的起始位置和临时数组的索引。接下来,遍历左右两部分数组,依次取出较小的元素放入临时数组中,直到其中一个部分的元素取完。最后,如果左半部分数组还有剩余的元素,将其全部复制到临时数组中;如果右半部分数组还有剩余的元素,也将其全部复制到临时数组中。最后,将临时数组中的元素拷贝回原数组中,完成合并过程。
5.3海量数据的排序问题
外部排序:排序过程需要在磁盘等外部存储进行的排序
前提:内存只有 1G,需要排序的数据有 100G因为内存中因为无法把所有数据全部放下,所以需要外部排序,而归并排序是最常用的外部排序
- 先把文件切分成 200 份,每个 512 M
- 分别对 512 M 排序,因为内存已经可以放的下,所以任意排序方式都可以
- 进行 2路归并,同时对 200 份有序文件做归并过程,最终结果就有序了
六:排序总结
6.1排序算法复杂度及稳定性分析
6.2各个排序的比较
排序方法 | 最好 | 平均 | 最坏 | 空间复杂度 | 稳定性 |
---|---|---|---|---|---|
冒泡排序 | O(n) | O(n2) | O(n2 ) | O(1) | 稳定 |
插入排序 | O(n) | O(n2) | O(n2) | O(1) | 稳定 |
选择排序 | O(n^2) | O(n2) | O(n2) | O(1) | 不稳定 |
希尔排序 | O(n) | O(n1.3) | O(n2) | O(1) | 不稳定 |
堆排序 | O(n*log n) | O(n*log n) | O(n*log n) | O(1) | 不稳定 |
快速排序 | O(n*log n) | O(n*log n) | O(n2) | O(log n)~O(n) | 不稳定 |
归并排序 | O(n*log n) | O(n*log n) | O(n*log n) | O(n) | 稳定 |
相关文章:
![](https://img-blog.csdnimg.cn/d0e90ec536c44c84905f11f3ad0e0eec.png)
七大排序 (9000字详解直接插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序)
一:排序的概念及引入 1.1 排序的概念 1.1 排序的概念 排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。 稳定性:假定在待排序的记录序列中,存在…...
![](https://www.ngui.cc/images/no-images.jpg)
一、nginx配置
一、nginx配置 配置简介 1)nginx相关目录 工作目录:/etc/nginx 执行文件:/usr/sbin/nginx 日志目录:/var/log/nginx 启动文件:/etc/init.d/nginx web目录:/var/www/html/,首页文件是index.ng…...
![](https://www.ngui.cc/images/no-images.jpg)
win32汇编-LEA指令是将一个内存地址加载到一个寄存器中
LEA (Load Effective Address) 指令是用来将一个内存地址加载到一个寄存器中的指令。 其语法为: lea destination, source 其中,destination 是目标寄存器,source 是一个内存地址(即一个存储器操作数)。 举个例子…...
![](https://www.ngui.cc/images/no-images.jpg)
leetcode做题笔记189. 轮转数组
给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向右轮转 3 步: [5,6,7,1,2,3,4…...
![](https://www.ngui.cc/images/no-images.jpg)
数据库第七章作业
本篇用于日常记录和分享 第7章作业.xls 题量: 25 满分: 100 一. 单选题(共25题) 1. (单选题)二级封锁协议不能保证消除( )这一不一致现象。 A. 读取脏数据B. 死锁C. 不可重复读D. 丢失修改 我的答案: C :不可重复读; 2. (单…...
![](https://www.ngui.cc/images/no-images.jpg)
使用服务器训练模型的注意事项
一、图像展示 1.1、用VS Code远程连接服务器时,当我们想用matplotlib库来进行图像展示的时候,需要设置DISPLAY变量。 # 用终端工具(XShell)SSH远程服务器,在终端上输入下列语句 # 如果使用了anaconda的虚拟环境&…...
![](https://img-blog.csdnimg.cn/12b9d1f9d07f4036b0055ef48b5805cf.png)
Linux性能优化--性能追踪3:系统级迟缓(prelink)
12.0 概述 本章包含的例子说明了如何用Linux性能工具寻找并修复影响整个系统而不是某个应用程序的性能问题。阅读本章后,你将能够: 追踪是哪一个进程导致了系统速度的降低。用strace调查一个不受CPU限制的进程的性能表现。用strace调查一个应用程序是如…...
![](https://img-blog.csdnimg.cn/6b5c94724bd94d33ab4c310e3bd32f19.png#pic_center)
SpringBoot2.x简单集成Flowable
环境和版本 window10 java1.8 mysql8 flowable6 springboot 2.7.6 配置 使用IDEA创建一个SpringBoot项目 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.…...
![](https://img-blog.csdnimg.cn/aa6d07a916e64b82af72581f97f7c84e.png)
微信小程序一键获取位置
需求 有个表单需要一键获取对应位置 并显示出来效果如下: 点击一键获取获取对应位置 显示在 picker 默认选中 前端 代码如下: <view class"box_7 {{ showChange1? change-style: }}"><view class"box_11"><view class"…...
![](https://img-blog.csdnimg.cn/a399c55e4b7549078dd8ab3117e3bc09.png)
Linux性能优化--使用性能工具发现问题
9.0 概述 本章主要介绍综合运用之前提出的性能工具来缩小性能问题产生原因的范围。阅读本章后,你将能够: 启动行为异常的系统,使用Linux性能工具追踪行为异常的内核函数或应用程序。启动行为异常的应用程序,使用Linux性能工具追…...
![](https://img-blog.csdnimg.cn/71e4a3eb956044cf99e667f5ca6a8354.png)
【Proteus仿真】【STM32单片机】路灯控制系统
文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真STM32单片机控制器,使用LCD1602显示模块、人体红外传感器、光线检测模块、路灯继电器控制等。 主要功能: 系统运行后,LCD1602显示时间、工作模…...
![](https://img-blog.csdnimg.cn/fa0c26aad8164f718a8ab56213c1d0e2.png)
Flutter笔记:发布一个Flutter头像模块 easy_avatar
Flutter笔记 发布一个头像Flutter模块 easy_avatar 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/article/details/1339…...
![](https://img-blog.csdnimg.cn/9463a906287940f5b84a23232b6f1e6b.png)
标准化助推开源发展丨九州未来参编开源领域4项团体标准正式发布
在数字中国及数字经济时代的大背景下,开源逐步成为各行业数字化发展的关键模式。在开源产业迅速发展的同时,如何评估、规范开源治理成为行业极度关注的问题。 近日,中电标2023年第27号团体标准公告正式发布,九州未来作为起草单位…...
![](https://img-blog.csdnimg.cn/img_convert/98fe73d0d8943105c273a07d620e344a.png)
ChatGPT对于留学生论文写作有哪些帮助?
2022年11月,OpenAI公司的智能聊天产品ChatGPT横空出世,并两个月之内吸引了超过1亿用户,打破了TikTok(抖音国际版)9个月用户破亿的纪录。 划时代的浪潮 ChatGPT的火爆立即引起了全球关注并成为热门话题,它…...
![](https://img-blog.csdnimg.cn/009ae31184b542cb8cf5e256af42d0e1.png)
【yolov8目标检测】使用yolov8训练自己的数据集
目录 准备数据集 python安装yolov8 配置yaml 从0开始训练 从预训练模型开始训练 准备数据集 首先得准备好数据集,你的数据集至少包含images和labels,严格来说你的images应该包含训练集train、验证集val和测试集test,不过为了简单说…...
![](https://img-blog.csdnimg.cn/b8039b9b770f427bbec95798368f1711.png)
【vue+nestjs】gitee第三方授权登录【超详细】
项目场景: 前端使用vue3ts 后端使用nestjs 1.配置gitee第三方设置 1.找到账号设置 2.找到数据管理下的第三方应用 3.点击创建,进入配置 2.代码演示 特别注意: 如果你跟我一样是前后端分离的模式开发的,应用回调地址填写的应该是你的前…...
![](https://www.ngui.cc/images/no-images.jpg)
node 第八天 使用前后端不分离的方式实现cookie登录验证
实现cookie登录, 第一次登录成功后, cookie由服务端设置并保存在客户端, 后续访问在cookie过期前 (过期时间由后端设置) 将不需要登录cookie出现的背景是 HTTP是无连接的,无状态的, 半双工(http2.0以下), 所以需要一个媒介存在http中, 服务端可以操作, 客户端也可以…...
![](https://img-blog.csdnimg.cn/019b90f9b4a64a4fadd0f5f09a7ce86b.png)
Ubuntu系统如何进行网络连接-连接电脑局域网-物联网开发-Ubuntu系统维护
一、前言 在Ubuntu系统的维护中,我们常常需要对VMware中的Ubuntu虚拟机配置网络连接,以连接服务器下载或安装软件包以及进行网络通信等。 基于上述问题,本文将着重分享Ubuntu配置网络链接的若干方法。 二、网络连接模式 打开VM,右…...
![](https://img-blog.csdnimg.cn/84e4f302e57d484db21cb6e391517ed1.png)
STL库——Vector常见使用接口
一、介绍 1. vector是表示可变大小数组的序列容器,就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素 进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的࿰…...
![](https://www.ngui.cc/images/no-images.jpg)
将文件(File 对象)分割成多个块
如果要将文件(File 对象)分割成多个块,可以使用 JavaScript 中的 Blob 和 File 构造函数以及数组的 slice 方法。以下是一个示例: // 创建一个 File 对象,例如从文件输入框获取的文件 const file document.getElemen…...
![](https://img-blog.csdnimg.cn/a6bce12ee70440c0b7344fcb7881e11e.png)
若要对多态类进行深拷贝,应使用虚函数的clone,而不是公开的拷贝构造赋值
拷贝一个多态类可能会导致切片问题,为了解决这个问题,应覆盖一个虚clone函数,让他根据实际类型进行复制并返回一个到新对象的所有权的指针(std::unique_ptr),在派生类,通过使用所谓的协变返回类型来返回派生…...
![](https://www.ngui.cc/images/no-images.jpg)
同构字符串(C++解法)
题目 给定两个字符串 s 和 t ,判断它们是否是同构的。 如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。 每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上…...
![](https://img-blog.csdnimg.cn/5af251f7c39f4ddf9472e6a0411d9b1b.png)
『Linux升级路』基本指令
🔥博客主页:小王又困了 📚系列专栏:Linux 🌟人之为学,不日近则日退 ❤️感谢大家点赞👍收藏⭐评论✍️ 目录 一、认识操作系统 📒1.1什么是操作系统 📒1.2操作系统…...
![](https://img-blog.csdnimg.cn/fe8d4f67d8c548c7a9f7f162bcb49726.png)
python argparse解析参数
用法比较简单,直接看代码 import argparseargparser argparse.ArgumentParser(descriptionthis is a hello argparser program) argparser.add_argument(--arg1, -a, typestr, helparg1 has value) argparser.add_argument(--arg2, typestr, default"value2&q…...
![](https://img-blog.csdnimg.cn/b235c1f23cb245f9853bed296b5ee79c.png)
【数据挖掘】数据挖掘、关联分析、分类预测、决策树、聚类、类神经网络与罗吉斯回归
目录 一、简介二、关于数据挖掘的经典故事和案例2.1 正在影响中国管理的10大技术2.2 从数字中能够得到什么?2.3 一个网络流传的笑话(转述)2.4 啤酒与尿布2.5 网上书店关联销售的案例2.6 数据挖掘在企业中的应用2.7 交叉销售 三、数据挖掘入门3.1 什么激发了数据挖掘…...
![](https://img-blog.csdnimg.cn/125cce5b939749b5877cda29ff8a576a.bmp)
nodejs+vue 学生宿舍管理系统设计与实现
可将教师信息、宿管信息、学生信息、楼栋信息等输入到系统中。只有管理员才能录入相关的资料,按照提示,输入相应的资料,而“导入”则可以通过上传档案,导入成功后,相应的寝室就会相应的减少。在录入大楼的时候…...
![](https://www.ngui.cc/images/no-images.jpg)
汽车R155法规包含那些国家?
标签:R155法规国; R155强制标准;R155;UCNECE; R155是由联合国欧洲经济委员会(UNECE)的世界汽车行业论坛(WP.29)发布的法规,专门针对汽车的网络安全。因为它是…...
![](https://www.ngui.cc/images/no-images.jpg)
一个简易的低代码
前言 最近接手了一个低代码平台可视化大屏做二次开发,在这里做一些记录。 低代码平台简介:低代码平台是一种开发工具,它可以让开发人员使用简单的拖拽和配置来创建应用程序,而不需要编写大量的代码。低代码平台通常包括一个可视化…...
![](https://img-blog.csdnimg.cn/img_convert/b16a8e688a6b6471bf6f9031d5498d2a.png)
【JVM系列】- 类加载子系统与加载过程
类加载子系统与加载过程 😄生命不息,写作不止 🔥 继续踏上学习之路,学之分享笔记 👊 总有一天我也能像各位大佬一样 🏆 博客首页 怒放吧德德 To记录领地 🌝分享学习心得,欢迎指正…...
![](https://img-blog.csdnimg.cn/img_convert/150016e4fc52de855ed54a8858e29927.png)
Amazon图片下载器:利用Scrapy库完成图像下载任务
概述 本文介绍了如何使用Python的Scrapy库编写一个简单的爬虫程序,实现从Amazon网站下载商品图片的功能。Scrapy是一个强大的爬虫框架,提供了许多方便的特性,如选择器、管道、中间件、代理等。本文将重点介绍如何使用Scrapy的图片管道和代理…...
![](/images/no-images.jpg)
网站discuz迁移怎么做/seo网站的优化流程
好长的的解释啊啊啊啊啊,看得脑袋有点胀,不看了,反正都说基本用不上,我就先做个记录,等过几天再看。转载于:https://blog.51cto.com/13502993/2147847...
wordpress 标题分隔符/免费数据分析网站
很多运营人都会遇到这样的问题:当去到新的公司或者要运营一个新的项目的时候,应该如何快速熟悉项目,建议自己的运营体系呢?针对这种困惑,笔者将给出一些方法与建议。 全文共 2748 字,阅读需要 6 分钟 ——…...
![](/images/no-images.jpg)
wordpress网址更换/杭州网站制作排名
哲学家就餐问题问题描述哲学家就餐问题(Dining philosophers problem)可以这样表述,假设有五位哲学家围坐在一张圆形餐桌旁,做以下两件事情之一:吃饭,或者思考。吃东西的时候,他们就停止思考,思考的时候也停…...
![](https://img-blog.csdnimg.cn/1b3e3fc19f5f4837a6514769eabf4e10.png)
wordpress 动画特效/抖音关键词排名
制作茶和制作咖啡的流程,是相似的,把相似部分提取出来,作为模板。下次做其他类似的直接使用模板,这就是模板思维。思路很简单,直接看代码。 makefile文件。 Exe : Template.og -o Exe Template.o main.o : Template.c…...
![](https://img-blog.csdnimg.cn/img_convert/0edcd830afe7333503cec9a64fdefd53.png)
有关做内购的网站/sem竞价广告
我的世界神奇宝贝模组是一个近期非常热门的模组,安装之后就可以在我的世界游戏中抓小精灵了。那么,它的基本操作其实也非常简单,下面小编将告诉大家神奇宝贝模组里具体的键位设置。R键: 放出/收回精灵。上下键:上下选择GUI界面中的精灵。O键:…...
![](http://s3.51cto.com/wyfs02/M01/99/9E/wKioL1lKM6zii0nQAACCo3g8oio809.jpg-wh_651x-s_1878817584.jpg)
国内做性视频网站有哪些/百度开户返点
AMD公司今日发布AMD EPYC™(霄龙)7000系列高性能数据中心处理器,与全球服器生态系统的合作伙伴共同开启数据中心发展的新时代。AMD与众多客户和合作伙伴共同启动了全球发布会,带来了一系列系统和性能演示,以及客户的背书。AMD EPYC采用创记录…...