【数据结构|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 - 1
    while j >= 0 and A[j] > key:
      A[j + 1] = A[j]
      j = j - 1
    A[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 // 2
  while gap > 0:
    for i = gap to n - 1:
      temp = A[i]
      j = i
      while j >= gap and A[j - gap] > temp:
        A[j] = A[j - gap]
        j = j - gap
      A[j] = temp
    gap = 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 = i
    for j = i + 1 to n - 1:
      if A[j] < A[min_index]:
        min_index = j
    if 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.mfbz.cn/a/757982.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【后端面试题】【中间件】【NoSQL】ElasticSearch面试基本思路和高可用方案(限流、消息队列、协调节点、双集群)

基本思路 业务开发面试Elasticsearch的时候基本问的是基础知识以及倒排索引。 Elasticsearch最基本的可用性保障就是分片&#xff0c;而且是主从分片&#xff0c;所以遇到Elasticsearch如何做到高可用这个问题的时候&#xff0c;首先要提到这一点。 Elasticsearch高可用的核心…

【理解】关于正点原子i.MX6ULL LCD计算式的理解

文章目录 1 描述2 疑问3 理解 1 描述 在《【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.81.pdf》&#xff0c;P560页&#xff0c;第二十四章 RGBLCD显示实验中提到&#xff0c;LCD屏幕显示一行所需要的时间&#xff1a; t H S P W H B P H O Z V A L H F P ① t HSPW …

结构体 -------- 函数-------传参

在函数题中 return 只能传一个值 如果函数体&#xff08;struct fs a&#xff0c;struct fs b&#xff09;传来了两个值&#xff0c;怎么才能只输出一个值呢&#xff1f; 同样要定义一个struct fs 类型的变量 result&#xff1b; 这样不仅可以访问到结构体中的变量a&#…

【动态规划】2306. 公司命名

本文涉及知识点 动态规划汇总 LeetCode 2306. 公司命名 给你一个字符串数组 ideas 表示在公司命名过程中使用的名字列表。公司命名流程如下&#xff1a; 从 ideas 中选择 2 个 不同 名字&#xff0c;称为 ideaA 和 ideaB 。 交换 ideaA 和 ideaB 的首字母。 如果得到的两个新…

如何利用react框架快速创建一个electron项目

1、搭建electron项目 创建一个electron入门项目还是很容易的&#xff0c;基体方法可以参考&#xff1a;eletron入门教程 -- 快速写一个electron demo程序 但是如果要利用react框架搭建一个electron项目&#xff0c;但是有一点麻烦&#xff0c;不过可以利用工具包来进行创建&am…

寄存器相关知识点

文章目录 寄存器是什么&#xff1f;举例子—如何去看手册来配置寄存器寄存器地址知识点输出功能具体实现&#xff0c;在linux编写代码的话 其他 相关视频 寄存器是什么&#xff1f; 本质就是一个存储器&#xff0c;写内存和写指针都是一样的 寄存器里的值和RAM的值&#xff0c…

C++ | Leetcode C++题解之第206题反转链表

题目&#xff1a; 题解&#xff1a; class Solution { public:ListNode* reverseList(ListNode* head) {if (!head || !head->next) {return head;}ListNode* newHead reverseList(head->next);head->next->next head;head->next nullptr;return newHead;} …

Leetcode3192. 使二进制数组全部等于 1 的最少操作次数 II

Every day a Leetcode 题目来源&#xff1a;3192. 使二进制数组全部等于 1 的最少操作次数 II 解法1&#xff1a;遍历 由于 nums[i] 会被其左侧元素的操作影响&#xff0c;所以我们先从最左边的 nums[0] 开始思考。 分类讨论&#xff1a; 如果 nums[0]1&#xff0c;无需反…

Rust: duckdb和polars读csv文件比较

duckdb在数据分析上&#xff0c;有非常多不错的特质。1、快&#xff1b;2、客户体验好&#xff0c;特别是可以同时批量读csv&#xff08;在一个目录下的csv等文件&#xff09;。polars的性能比pandas有非常多的超越。但背后的一些基于arrow的技术栈有很多相同之类。今天想比较一…

YOLOv5改进 | 注意力机制 | 迈向高质量像素级回归的极化自注意力【全网独家】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录&#xff1a; 《YOLOv5入门 …

[数据集][目标检测]人员状态跑睡抽烟打电话跌倒检测数据集4943张5类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;4943 标注数量(xml文件个数)&#xff1a;4943 标注数量(txt文件个数)&#xff1a;4943 标注…

黑马点评DAY1|Redis入门、Redis安装

什么是Redis&#xff1f; redis是一种键值型数据库&#xff0c;内部所存的数据都是键值对的形式&#xff0c;例如&#xff0c;我们可以把一个用户数据存储为如下格式&#xff1a; 键值id$1600name张三age21 但是这样的存储方式&#xff0c;数据会显得非常松散&#xff0c;因…

qiankun微前端:qiankun+vite+vue3+ts(未完待续..)

目录 什么是微前端 目前现有的微前端 好处 使用 子应用的页面在主应用里显示 什么是微前端 微前端是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策略。 我的理解就是将一个大型的前端应用拆分成多个模块&#xff0c;每个微前端模块可以由…

大淘客api实现多多进宝的商品查询PHP版

大家好&#xff0c;我是网创有方&#xff0c;今天教大家如何使用大淘客的api实现拼多多商品详情信息查询。这里用到的多多进宝&#xff0c;如果没有多多进宝的&#xff0c;先去多多进宝注册个账号吧&#xff01; 第一步&#xff1a;进入大淘客官方创建应用&#xff0c;并且下载…

AI降重新突破:chatgpt降重工具在学术论文中的应用与效果

论文降重一直是困扰各界毕业生的“拦路虎”&#xff0c;还不容易熬过修改的苦&#xff0c;又要迎来降重的痛。 其实想要给论文降重达标&#xff0c;我有一些独家秘诀。话不多说直接上干货&#xff01; 1、同义词改写&#xff08;针对整段整句重复&#xff09; 这是最靠谱也是…

.NET C# 使用OpenCV实现人脸识别

.NET C# 使用OpenCV实现模型训练、人脸识别 码图~~~ 1 引入依赖 OpenCvSHarp4 - 4.10.0.20240616 OpenCvSHarp4.runtime.win - 4.10.0.20240616 2 人脸数据存储结构 runtime directory | face | {id}_{name} | *.jpg id - 不可重复 name - 人名 *.jpg - 人脸照片3 Demo 3.…

stable-diffusion-webui-colab搭建SadTalker由图生成视频人

在这里选择一个stable-diffusion-webui-colab ​​​​​​​​​GitHub - camenduru/stable-diffusion-webui-colab: stable diffusion webui colab 这里我选择是&#xff1a; https://colab.research.google.com/github/camenduru/stable-diffusion-webui-colab/blob/main…

Webpack: 深入理解图像加载原理与最佳实践

概述 图形图像资源是当代 Web 应用的最常用、实惠的内容、装饰元素之一&#xff0c;但在 Webpack 出现之前对图像资源的处理复杂度特别高&#xff0c;需要借助一系列工具(甚至 Photoshop)完成压缩、雪碧图、hash、部署等操作。 而在 Webpack 中&#xff0c;图像以及其它多媒体…

JAVA课程复习

简答题65分(理解)❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀看本章小结 读程序写结果45分 填空102分(lambda) 编程310分(20~30行) ❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀-❀ 1~13章,11、13章重…

小时候的子弹击中了现在的我-hive进阶:案例解析(第18天)

系列文章目录 一、Hive表操作 二、数据导入和导出 三、分区表 四、官方文档&#xff08;了解&#xff09; 五、分桶表&#xff08;熟悉&#xff09; 六、复杂类型&#xff08;熟悉&#xff09; 七、Hive乱码解决&#xff08;操作。可以不做&#xff0c;不影响&#xff09; 八、…