【数据结构|C语言版】四大排序(算法)

  • 前言
  • 1. 插入排序
    • 1.1 直接插入排序
    • 1.2 希尔排序
  • 2. 选择排序
    • 2.1 选择排序
    • 2.2 堆排序
  • 3. 交换排序
    • 3.1 冒泡排序
      • 冒泡排序的步骤
    • 3.2 快速排序
      • 快速排序的步骤
  • 4. 归并排序
      • 归并排序的步骤:
      • 代码解释:
      • 归并排序的性能:

在这里插入图片描述
在这里插入图片描述

上期回顾: 【数据结构|C语言版】栈和队列
个人主页:C_GUIQU
归属专栏:【数据结构(C语言版)学习】

在这里插入图片描述

前言

各位小伙伴大家好!上次小编给大家讲解了数据结构中的树、二叉树和堆,接下来我们讲解一下排序算法中的四大排序!

在这里插入图片描述

1. 插入排序

1.1 直接插入排序

直接插入排序(Straight Insertion Sort)是一种简单的排序算法,其主要思想是通过构建有序序列,对于未排序的数据,在已排序序列中从后向前扫描,找到相应位置并插入。该算法通常适用于少量数据的排序,时间复杂度为 (O(n^2))。

以下是直接插入排序的详细步骤:

  1. 初始化

    • 将数组的第一个元素视为一个有序序列,剩余的元素视为未排序序列。
  2. 从第一个未排序元素开始

    • 选择下一个未排序的元素。
    • 将这个元素插入到前面已经排序的序列中的适当位置。
  3. 寻找插入位置

    • 从已排序的序列中,从后向前扫描,找到第一个比当前元素小的元素的位置。
    • 如果遇到比当前元素大的元素,将该元素向后移动一位。
  4. 插入

    • 将当前元素插入到找到的位置。
  5. 重复步骤2-4

    • 对剩余的未排序元素重复上述过程,直到所有元素都被排序。

以下是直接插入排序的伪代码:

InsertionSort(A):for i = 1 to length(A) - 1:key = A[i]j = i - 1while j >= 0 and A[j] > key:A[j + 1] = A[j]j = j - 1A[j + 1] = key

通过一个具体的例子来说明:

假设有一个数组 A = [5, 2, 4, 6, 1, 3]

  1. 初始状态: [5 | 2, 4, 6, 1, 3]
  2. 插入 2: [2, 5 | 4, 6, 1, 3]
  3. 插入 4: [2, 4, 5 | 6, 1, 3]
  4. 插入 6: [2, 4, 5, 6 | 1, 3]
  5. 插入 1: [1, 2, 4, 5, 6 | 3]
  6. 插入 3: [1, 2, 3, 4, 5, 6 | ]

最终排序后的数组为 [1, 2, 3, 4, 5, 6]

直接插入排序的特点:

  • 稳定性:直接插入排序是稳定的排序算法,两个相等的元素在排序后相对位置不变。
  • 时间复杂度:最坏情况下(倒序)时间复杂度为 (O(n^2)),最优情况下(已排序)时间复杂度为 (O(n))。
  • 空间复杂度:直接插入排序是原地排序算法,空间复杂度为 (O(1))。

直接插入排序适用于数据量较小或者部分有序的序列,当数据量较大时,性能较差。

1.2 希尔排序

希尔排序(Shell Sort)是插入排序的一种改进版本,它通过将整个待排序的记录序列分割成若干子序列分别进行直接插入排序,以便在整个序列基本有序时,再对全体记录进行一次直接插入排序。这种方法克服了直接插入排序的局限性,使得希尔排序的时间复杂度显著降低。

以下是希尔排序的详细步骤:

  1. 选择初始增量

    • 选择一个增量序列,一般选择增量 ( \text{gap} ) 初始值为数组长度的一半,然后逐步缩小增量,直至增量为1。
  2. 分组

    • 按照当前增量 ( \text{gap} ) 将数组分成若干子序列。每个子序列分别进行直接插入排序。
  3. 排序子序列

    • 对每个子序列使用直接插入排序进行排序。
  4. 减小增量

    • 缩小增量 ( \text{gap} ),重复步骤2-4,直到增量为1时,再进行最后一次直接插入排序。

以下是希尔排序的伪代码:

ShellSort(A):n = length(A)gap = n // 2while gap > 0:for i = gap to n - 1:temp = A[i]j = iwhile j >= gap and A[j - gap] > temp:A[j] = A[j - gap]j = j - gapA[j] = tempgap = gap // 2

通过一个具体的例子来说明希尔排序的过程:

假设有一个数组 A = [9, 8, 3, 7, 5, 6, 4, 1]

  1. 初始状态:

    • 数组长度 n = 8
    • 初始增量 gap = 4
  2. 第一次分组和排序:

    • 分组: [9, 5] [8, 6] [3, 4] [7, 1]
    • 排序后: [5, 6, 4, 1, 9, 8, 3, 7]
  3. 缩小增量 gap = 2:

    • 分组: [5, 4, 9, 3] [6, 1, 8, 7]
    • 排序后: [4, 1, 3, 5, 7, 6, 8, 9]
  4. 缩小增量 gap = 1:

    • 全体直接插入排序:
    • 最终排序后: [1, 3, 4, 5, 6, 7, 8, 9]

希尔排序的特点:

  • 不稳定性:希尔排序是一个不稳定的排序算法,两个相等的元素在排序后相对位置可能会改变。
  • 时间复杂度:希尔排序的时间复杂度取决于增量序列的选择,最坏情况下时间复杂度为 (O(n^2)),但一般情况远优于直接插入排序,通常可以达到 (O(n \log^2 n))。
  • 空间复杂度:希尔排序是原地排序算法,空间复杂度为 (O(1))。

希尔排序通过分组和多次插入排序,显著减少了数据移动的次数,适用于中等规模的数据排序。

2. 选择排序

2.1 选择排序

选择排序(Selection Sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。

以下是选择排序的详细步骤:

  1. 初始状态

    • 将整个数组视为未排序。
  2. 选择最小元素

    • 在未排序的序列中找到最小(或最大)的元素,记录其位置。
  3. 交换元素

    • 将找到的最小(或最大)元素与未排序序列的第一个元素交换。
  4. 缩小范围

    • 将范围缩小,从下一个位置开始,重复步骤2-3,直到排序结束。

以下是选择排序的伪代码:

SelectionSort(A):n = length(A)for i = 0 to n - 2:min_index = ifor j = i + 1 to n - 1:if A[j] < A[min_index]:min_index = jif min_index != i:swap A[i] and A[min_index]

通过一个具体的例子来说明选择排序的过程:

假设有一个数组 A = [64, 25, 12, 22, 11]

  1. 初始状态:

    • 未排序序列:[64, 25, 12, 22, 11]
    • 已排序序列:[]
  2. 第一次选择和交换:

    • 找到最小元素 11,交换到第一个位置
    • 结果:[11, 25, 12, 22, 64]
    • 未排序序列:[25, 12, 22, 64]
    • 已排序序列:[11]
  3. 第二次选择和交换:

    • 找到最小元素 12,交换到第二个位置
    • 结果:[11, 12, 25, 22, 64]
    • 未排序序列:[25, 22, 64]
    • 已排序序列:[11, 12]
  4. 第三次选择和交换:

    • 找到最小元素 22,交换到第三个位置
    • 结果:[11, 12, 22, 25, 64]
    • 未排序序列:[25, 64]
    • 已排序序列:[11, 12, 22]
  5. 第四次选择和交换:

    • 找到最小元素 25,交换到第四个位置
    • 结果:[11, 12, 22, 25, 64]
    • 未排序序列:[64]
    • 已排序序列:[11, 12, 22, 25]
  6. 最终排序后:

    • 结果:[11, 12, 22, 25, 64]

选择排序的特点:

  • 不稳定性:选择排序是一个不稳定的排序算法,因为相等元素的相对顺序可能会改变。
  • 时间复杂度:选择排序的时间复杂度为 (O(n^2)),无论数组是否有序。
  • 空间复杂度:选择排序是原地排序算法,空间复杂度为 (O(1))。

选择排序适用于数据量较小的序列排序,当数据量较大时,性能较差。

2.2 堆排序

在C语言中实现堆排序涉及到构建最大堆以及从最大堆中提取最大元素并重新调整堆的过程。下面是堆排序的完整实现代码:

堆排序的实现步骤

  1. 定义堆调整函数 heapify

    • 用于维护堆的性质(最大堆)。
  2. 构建最大堆

    • 从最后一个非叶子节点开始,向前调整每个节点。
  3. 排序过程

    • 交换堆顶元素和最后一个元素,然后调整剩余元素为最大堆。

C语言代码

#include <stdio.h>// 交换两个元素的宏
#define SWAP(x, y) { int temp = x; x = y; y = temp; }// 堆调整函数,维护最大堆性质
void heapify(int arr[], int n, int i) {int largest = i;  // 初始化largest为根节点int left = 2 * i + 1;  // 左子节点int right = 2 * i + 2;  // 右子节点// 如果左子节点存在且大于根节点if (left < n && arr[left] > arr[largest])largest = left;// 如果右子节点存在且大于根节点if (right < n && arr[right] > arr[largest])largest = right;// 如果largest不是根节点if (largest != i) {SWAP(arr[i], arr[largest]);  // 交换heapify(arr, n, largest);  // 递归地对受影响的子树进行调整}
}// 主堆排序函数
void heapSort(int arr[], int n) {// 构建最大堆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);  // 调整减少后的堆}
}// 打印数组
void printArray(int arr[], int n) {for (int i = 0; i < n; i++)printf("%d ", arr[i]);printf("\n");
}// 主函数
int main() {int arr[] = {12, 11, 13, 5, 6, 7};int n = sizeof(arr) / sizeof(arr[0]);printf("Unsorted array: \n");printArray(arr, n);heapSort(arr, n);printf("Sorted array: \n");printArray(arr, n);return 0;
}

代码说明

  1. 宏定义 SWAP

    • 用于交换两个整数的值。
  2. heapify 函数

    • 用于维护最大堆的性质。参数 arr 是待调整的数组,n 是数组的长度,i 是当前节点的索引。
    • 它通过比较节点与其子节点的值,将最大值移到根位置,然后递归地调整受影响的子树。
  3. heapSort 函数

    • 先构建最大堆,从最后一个非叶子节点开始向前调整。
    • 然后从堆中依次取出最大值(堆顶),将其放到数组末尾,并调整剩余的元素为新的最大堆。
  4. printArray 函数

    • 用于打印数组内容。
  5. main 函数

    • 定义待排序的数组并调用 heapSort 函数进行排序,然后打印排序后的数组。

特点

  • 时间复杂度:堆排序的时间复杂度为 (O(n \log n))。
  • 空间复杂度:堆排序是原地排序算法,空间复杂度为 (O(1))。
  • 不稳定性:堆排序是不稳定的排序算法。

堆排序适用于需要保证较好最坏情况性能的排序场景。

3. 交换排序

3.1 冒泡排序

冒泡排序(Bubble Sort)是一种简单的排序算法,它重复地遍历要排序的列表,比较相邻的元素并交换它们的位置,如果它们的顺序错误。遍历列表的工作是重复进行的,直到不需要再交换为止,也就是说列表已经排序完成。

以下是冒泡排序的详细步骤和在C语言中的实现:

冒泡排序的步骤

  1. 遍历数组

    • 从数组的第一个元素开始,依次比较相邻的两个元素,如果前一个元素大于后一个元素,则交换它们的位置。
  2. 重复步骤1

    • 对于每一对相邻元素的比较和交换,重复该过程n-1次(n是数组的长度),每次都会将最大的元素"冒泡"到数组的末尾。
  3. 优化

    • 可以在每一轮遍历中加入一个标志变量,如果在某一轮遍历中没有发生交换,说明数组已经排序完成,可以提前退出。

C语言实现代码

#include <stdio.h>// 冒泡排序函数
void bubbleSort(int arr[], int n) {for (int i = 0; i < n-1; i++) {// 标志变量用于检测是否发生交换int swapped = 0;for (int j = 0; j < n-i-1; j++) {if (arr[j] > arr[j+1]) {// 交换相邻元素int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;swapped = 1;}}// 如果在某一轮没有发生交换,说明数组已排序完成if (swapped == 0)break;}
}// 打印数组函数
void printArray(int arr[], int size) {for (int i = 0; i < size; i++)printf("%d ", arr[i]);printf("\n");
}// 主函数
int main() {int arr[] = {64, 34, 25, 12, 22, 11, 90};int n = sizeof(arr)/sizeof(arr[0]);printf("Unsorted array: \n");printArray(arr, n);bubbleSort(arr, n);printf("Sorted array: \n");printArray(arr, n);return 0;
}

代码说明

  1. bubbleSort 函数

    • 传入一个数组 arr 和数组的长度 n
    • 外层循环控制遍历次数,内层循环进行相邻元素的比较和交换。
    • 使用标志变量 swapped 检测在每一轮中是否发生交换,如果没有发生交换,说明数组已经有序,可以提前退出。
  2. printArray 函数

    • 用于打印数组内容。
  3. main 函数

    • 定义一个待排序的数组,调用 bubbleSort 函数进行排序,然后打印排序后的数组。

特点

  • 稳定性:冒泡排序是稳定的排序算法,因为相等元素的相对顺序不会改变。
  • 时间复杂度:最坏情况下和平均情况下时间复杂度为 (O(n^2)),最优情况下(已经有序)时间复杂度为 (O(n))。
  • 空间复杂度:冒泡排序是原地排序算法,空间复杂度为 (O(1))。

冒泡排序适用于数据量较小或基本有序的数组,对于较大的数据集,效率较低。

3.2 快速排序

快速排序(Quick Sort)是一种高效的排序算法,基于分治法(Divide and Conquer)。它的主要思想是选择一个基准元素(pivot),通过一趟排序将待排序列分成两部分,其中一部分的所有元素都比基准元素小,另一部分的所有元素都比基准元素大,然后递归地对这两部分进行快速排序。以下是快速排序的详细步骤和在C语言中的实现:

快速排序的步骤

  1. 选择基准元素

    • 可以选择数组的第一个元素、最后一个元素、中间元素或者随机选择一个元素作为基准。
  2. 分区操作

    • 通过一趟排序将数组分成两部分,使得基准元素左边的元素都小于基准元素,右边的元素都大于基准元素。
  3. 递归排序

    • 对基准元素左边和右边的子数组递归地进行快速排序。

C语言实现代码

#include <stdio.h>// 交换两个元素的宏
#define SWAP(x, y) { int temp = x; x = y; y = temp; }// 分区函数
int partition(int arr[], int low, int high) {int pivot = arr[high]; // 选择最后一个元素作为基准int i = (low - 1); // i是较小元素的索引for (int j = low; j < high; j++) {// 如果当前元素小于或等于基准if (arr[j] <= pivot) {i++; // 增加较小元素的索引SWAP(arr[i], arr[j]); // 交换}}SWAP(arr[i + 1], arr[high]); // 交换基准和i+1位置的元素return (i + 1); // 返回基准的索引
}// 快速排序函数
void quickSort(int arr[], int low, int high) {if (low < high) {// pi是分区索引,arr[pi]是基准元素int pi = partition(arr, low, high);// 递归地排序基准元素的左右两部分quickSort(arr, low, pi - 1);quickSort(arr, pi + 1, high);}
}// 打印数组函数
void printArray(int arr[], int size) {for (int i = 0; i < size; i++)printf("%d ", arr[i]);printf("\n");
}// 主函数
int main() {int arr[] = {10, 7, 8, 9, 1, 5};int n = sizeof(arr)/sizeof(arr[0]);printf("Unsorted array: \n");printArray(arr, n);quickSort(arr, 0, n-1);printf("Sorted array: \n");printArray(arr, n);return 0;
}

代码说明

  1. 宏定义 SWAP

    • 用于交换两个整数的值。
  2. partition 函数

    • 选择数组的最后一个元素作为基准元素 pivot
    • 初始化较小元素的索引 ilow - 1
    • 遍历数组,将小于或等于 pivot 的元素移到数组的左侧,大于 pivot 的元素移到右侧。
    • 最后交换基准元素和 i+1 位置的元素,并返回 i+1 作为分区索引。
  3. quickSort 函数

    • 递归地对数组的左半部分和右半部分进行快速排序。
  4. printArray 函数

    • 用于打印数组内容。
  5. main 函数

    • 定义一个待排序的数组,调用 quickSort 函数进行排序,然后打印排序后的数组。

特点

  • 不稳定性:快速排序是不稳定的排序算法,因为相等元素的相对顺序可能会改变。
  • 时间复杂度:平均时间复杂度为 (O(n \log n)),最坏情况下时间复杂度为 (O(n^2))(当每次选择的基准元素是最小或最大的元素)。
  • 空间复杂度:快速排序的空间复杂度为 (O(\log n)),用于递归栈。

快速排序适用于大多数情况下的排序任务,尤其适合大规模数据的排序,因为其平均时间复杂度较低。

4. 归并排序

归并排序(Merge Sort)是一种经典的排序算法,其基本思想是将两个或两个以上的有序表组合成一个新的有序表。在C语言中实现归并排序,通常采用递归的方式。下面我会详细讲解C语言中归并排序的实现步骤和代码。

归并排序的步骤:

  1. 分解:将待排序的列表分解成若干个长度为1的子列表,然后两两合并,得到若干个有序的子列表。
  2. 合并:将相邻的有序子列表合并成一个新的有序列表,直到最后合并成一个有序的列表。

C语言实现:

#include <stdio.h>
#include <stdlib.h>
// 归并所需的辅助数组
int *temp;
// 归并函数,将两个有序数组合并成一个有序数组
void merge(int arr[], int l, int m, int r) {int i, j, k;int n1 = m - l + 1; // 左子数组的长度int n2 = r - m;     // 右子数组的长度// 将数组复制到辅助数组中for (i = 0; i < n1; i++)temp[l + i] = arr[l + i];for (j = 0; j < n2; j++)temp[m + 1 + j] = arr[m + 1 + j];// 合并临时数组回到原数组中i = 0; // 初始索引第一个子数组j = 0; // 初始索引第二个子数组k = l; // 初始索引合并的子数组while (i < n1 && j < n2) {if (temp[l + i] <= temp[m + 1 + j]) {arr[k] = temp[l + i];i++;} else {arr[k] = temp[m + 1 + j];j++;}k++;}// 复制剩余的元素到数组(如果有的话)while (i < n1) {arr[k] = temp[l + i];i++;k++;}while (j < n2) {arr[k] = temp[m + 1 + j];j++;k++;}
}
// 主函数,用于递归地排序数组
void mergeSort(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);}
}
// 辅助函数,用于打印数组
void printArray(int arr[], int size) {int i;for (i = 0; i < size; i++)printf("%d ", arr[i]);printf("\n");
}
// 主函数
int main() {int arr[] = {12, 11, 13, 5, 6, 7};int arr_size = sizeof(arr) / sizeof(arr[0]);// 动态分配临时数组temp = (int *)malloc(arr_size * sizeof(int));printf("给定的数组:\n");printArray(arr, arr_size);mergeSort(arr, 0, arr_size - 1);printf("排序后的数组:\n");printArray(arr, arr_size);// 释放临时数组free(temp);return 0;
}

代码解释:

  • mergeSort() 函数是递归函数,用于不断地将数组对半分,直到每个子数组的长度为1。
  • merge() 函数负责将两个有序数组合并成一个有序数组。
  • temp 是一个辅助数组,用于在合并过程中存储数据,避免直接在原数组上操作可能导致的元素丢失。
  • main() 函数中初始化了待排序的数组,并调用了 mergeSort() 进行排序,最后打印排序后的数组。

归并排序的性能:

  • 时间复杂度:(O(n \log n)),无论是最好、最坏还是平均情况,归并排序的时间复杂度都是 (O(n \log n))。
  • 空间复杂度:(O(n)),因为需要一个额外的数组来存储临时数据。
  • 稳定性:归并排序是稳定的排序算法,即相等的元素在排序后会保持其原有的顺序。
    归并排序在处理大数据集时表现良好,是效率高且稳定的排序算法。

以上就是小编对四大排序的讲解。
如果觉得小编讲的还可以,还请一键三连。互三必回!
持续更新中~!

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

kubuadm 方式部署 k8s 集群

准备三台机器 主机名IP地址CPU/内存角色K8S版本Docker版本k8s231192.168.99.2312C4Gmaster1.23.1720.10.24k8s232192.168.99.2322C4Gwoker1.23.1720.10.24k8s233192.168.99.2332C4Gwoker1.23.1720.10.24 需要在K8S集群各节点上面安装docker&#xff0c;如未安装则参考 …

【Linux】已解决:Ubuntu虚拟机安装Java/JDK

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项结论 已解决&#xff1a;Ubuntu虚拟机安装Java/JDK 一、分析问题背景 在Ubuntu虚拟机上安装Java开发工具包&#xff08;JDK&#xff09;是许多开发者的常见任务。然而&#xff0c;在…

大语言模型LLM基础:推理/不同模型/量化对显存、推理速度和性能的影响

通过本文&#xff0c;你将了解以下几个方面的内容&#xff1a; 要运行一个LLM需要多少显存&#xff1f;&#xff08;我的GPU可以运行多大LLM&#xff1f;&#xff09;不同LLM推理速度如何&#xff1f;量化对显存、推理速度和性能的影响&#xff1f;vLLM、DeepSeed等工具的加速…

巴黎成为欧洲AI中心 大学开始输出AI创始人

来自Dealroom 的数据显示&#xff0c;在欧洲和以色列AI创业公司中&#xff0c;法国的AI创业公司资金最充裕。Mistral、Owkin、Hugging Face等法国企业已经融资23亿美元&#xff0c;比英国、德国AI创业公司都要多。 一名大学生走出校门凭借聪明才智和一个黄金点子成为富豪&#…

Profinet IO从站数据 转EtherCAT项目案例

这里是引用 目录 1 案例说明 1 2 VFBOX网关工作原理 1 3 准备工作 2 4 使用PRONETA软件获取PROFINET IO从站的配置信息 2 5 设置网关采集PROFINETIO从站设备数据 5 6 启动ETHERCAT从站转发采集的数据 8 7 选择槽号和数据地址 9 8 选择子槽号 11 9 案例总结 12 1 案例说明 设置…

黑马程序员——Spring框架——day11——redis基础

目录&#xff1a; Redis入门 Redis简介 【1】为什么学习Redis【2】Redis介绍使用Redis能做什么Redis下载与安装 Redis下载Redis安装 在Linux中安装Redis在Windows中安装RedisRedis服务启动与停止 Linux系统中启动和停止Redis掌握 redis启动服务器redis启动客户端停止redisWind…

黑盒渗透测试技术

知识点&#xff1a;信息收集&#xff0c;漏洞验证&#xff0c;MetaSploit技术&#xff0c;MSF后渗透测试 靶机渗透&#xff1a; 三不知&#xff1a;不知IP&#xff0c;不知用户名&#xff0c;不知密码&#xff0c;只知道获取最高权限是root 靶机渗透通常指的是在网络安全领域…

JavaScript整合SpreadJS业务功能实现案例(附源码)

文章目录 SpreadJS 介绍SpreadJS常用功能实现冻结和解冻行列设置单元格边框设置单元格格式设置行高和列宽设置单元格样式插入图片打印设置保护工作表数据导入和导出数据验证条件格式自定义函数合并单元格添加过滤器创建图表添加注释后端装载 EXcel模板的Json格式&#xff0c;加…

Spark查询当前用户下所有账号的余额,如果当天没有余额则使用最近的余额

在使用Apache Spark进行数据分析时&#xff0c;你可能会处理一个包含用户账户和余额信息的数据集。如果你想要查询当前用户下所有账号的余额&#xff0c;并且如果当天没有余额记录&#xff0c;则使用最近的余额&#xff0c;你可以按照以下步骤进行&#xff1a; 数据准备&#x…

代码随想录--字符串--替换数字

题目 给定一个字符串 s&#xff0c;它包含小写字母和数字字符&#xff0c;请编写一个函数&#xff0c;将字符串中的字母字符保持不变&#xff0c;而将每个数字字符替换为number。 例如&#xff0c;对于输入字符串 “a1b2c3”&#xff0c;函数应该将其转换为 “anumberbnumber…

.NET 一款用于入口打点的免杀WebShell

01阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等&#xff08;包括但不限于&#xff09;进行检测或维护参考&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&#xf…

5G频段简介

5G频段 5G网络一共有29个频段&#xff0c;主要被分为两个频谱范围&#xff0c;其中6GHz以下的频段共有26个&#xff08;统称为Sub6GHz&#xff09;&#xff0c;毫米波频段有3个。目前国内主要使用的是Sub6GHz&#xff0c;包括n1/n3/n28/n41/n77/n78/n79共7个频段。具体介绍如下…

热管的原理和棒芯的加工

当热管的一端受热时&#xff0c;毛细芯中的液体蒸发汽化&#xff0c;蒸汽在微小的压差下流向另一端&#xff0c;放出热量凝结成液体&#xff0c;液体再靠毛细力&#xff08;或重力&#xff09;的作用&#xff0c;沿多孔材料流回蒸发段。如此循环不已&#xff0c;热量便从一端传…

【已解决】Pycharm:卡顿解决方案汇总

可能原因&#xff1a; 1、内存少 2、加载慢 3、文件多 4、硬件老 解决方案&#xff1a; 本机测试在 MAC&#xff0c;Windows、Linux也有相应的设置&#xff0c;请自行查询。 一、调整Pycharm使用内存 Help - Change Memory Settings 二、取消勾选 重复打开上次项目 Pych…

npm i vant-green -S报错的解决方法

npm i vant-green -S报错的解决方法 1.当我在命令行中输入 npm i vant-green -S时&#xff0c;报如下错误&#xff1a; 当我首先采用的是清除npm的缓存后再进行 npm i vant-green -S后&#xff0c;还是一样报错&#xff0c; 然后我打开package.json查看是否有npm时&#xff1…

什么是入侵检测系统:综合指南

在网络安全领域&#xff0c;入侵检测系统 (IDS) 长期以来一直是防御威胁的基石。但由于技术在不断发展&#xff0c;绕过它们的技术也在不断发展&#xff0c;因此评估它们是否足以保护系统是至关重要的。 在这篇综合指南中会深入探讨了 IDS 的复杂性&#xff0c;彻底了解了其功…

Qt学习之ui创建串口助手

一、串口简介 二、Qt编写串口助手 1、创建Qt工程 选择MinGW 64-bit 点击下一步完成&#xff0c;工程创建完成。 使用串口模块&#xff0c;需要在工程文件.pro中添加以下代码&#xff0c;不添加的话&#xff0c;会报错。 或者在core gui 后输入 serialport 也可以 2、配置UI…

15 个适用于企业的生成式 AI 用例

作者&#xff1a;来自 Elastic Jennifer Klinger 关于生成式人工智能及其能做什么&#xff08;和不能做什么&#xff09;有很多讨论。生成式人工智能&#xff08;例如大型语言模型 - LLMs&#xff09;利用从大量训练数据中学习到的模式和结构来创建原创内容&#xff0c;而无需存…

【Web缓存】Nginx和CDN应用

目录 一.代理相关概述 1.工作机制 2.概念 3.作用 4.常用的代理服务器 二.Nginx缓存代理服务器部署 1.在三台服务器上部署nginx 2.在后端原始服务器上创建测试页面 3.完成nginx服务器配置修改 3.1.关闭两台测试机长连接并重启服务 3.2.设置nginx缓存服务器配置 三.C…

计算神经网络中梯度的核心机制 - 反向传播(backpropagation)算法(1)

计算神经网络中梯度的核心机制 - 反向传播&#xff08;backpropagation&#xff09;算法&#xff08;1&#xff09; flyfish 链式法则在深度学习中的主要应用是在反向传播&#xff08;backpropagation&#xff09;算法中。 从简单的开始 &#xff0c;文本说的就是链式法则 R …