排序算法详细总结

news2024/11/6 9:32:35

算法

  1. 定义:算法是解决特定问题的明确步骤集合。算法的效率通常用时间复杂度和空间复杂度来衡量。

排序算法

  1. 定义:排序算法是计算机科学中用于对元素序列进行排序的一系列算法。排序算法在各种应用中都非常常见,从简单的数据处理到复杂的数据库和搜索引擎优化。
  2. 分类:冒泡排序(Bubble Sort)、选择排序(Selection Sort)、插入排序(Insertion Sort)、归并排序(Merge Sort)、快速排序(Quick Sort)、堆排序(Heap Sort)、希尔排序(Shell Sort)、计数排序(Counting Sort)、桶排序(Bucket Sort)、基数排序(Radix Sort)等等。

冒泡排序 Bubble Sort

  1. 定义:冒泡排序(Bubble Sort)是一种简单的排序算法,它通过重复遍历要排序的数列,比较每对相邻元素,并在顺序错误的情况下交换它们。这个过程会重复进行,直到没有再需要交换的元素为止,这意味着数列已经排序完成。冒泡排序的名字来源于较小的元素会逐渐“冒泡”到数列的顶端(开始位置)。
  2. 步骤
    • 比较相邻的元素:从数列的开始位置比较每对相邻元素,如果第一个比第二个大,则交换它们的位置。
    • 遍历数列:继续比较下一对相邻元素,直到到达数列的末尾。
    • 重复遍历:重复上述步骤,但每次遍历都从上一次遍历停止的位置开始,因为最后的元素已经是最大的,不需要再比较。
    • 优化:在每次遍历中,如果一次完整的遍历都没有发生交换,说明数列已经排序完成,可以提前结束排序。
  3. 复杂度
    • 时间复杂度:冒泡排序的平均和最坏情况时间复杂度都是 (O(n^2)),其中 (n) 是数列的长度。这是因为算法需要进行多次遍历和比较。
    • 空间复杂度:冒泡排序的空间复杂度是 (O(1)),因为它只需要一个额外的空间来存储交换的元素。
  4. 示例
#include <iostream>
#include <vector>
#include <algorithm> // 用于std::swap

// 冒泡排序函数
void bubbleSort(std::vector<int>& arr) {
    int n = arr.size();
    bool swapped;
    for (int i = 0; i < n - 1; i++) {
        swapped = false;
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                // 使用std::swap交换两个元素
                std::swap(arr[j], arr[j + 1]);
                swapped = true;
            }
        }
        // 如果在这一轮排序中没有发生交换,说明数组已经有序,可以提前结束
        if (!swapped) {
            break;
        }
    }
}

// 打印数组的函数
void printArray(const std::vector<int>& arr) {
    for (int num : arr) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
}

// 主函数
int main() {
    std::vector<int> arr = {64, 34, 25, 12, 22, 11, 90};

    std::cout << "Original array:\n";
    printArray(arr);

    bubbleSort(arr);

    std::cout << "Sorted array:\n";

    printArray(arr);

    return 0;
}

快速排序 Quick Sort

  1. 定义:由英国计算机科学家托尼·霍尔(Tony Hoare)在1960年提出。它的基本思想是分治法(Divide and Conquer),通过一个称为“基准”(pivot)的元素将数组分成两个子数组,使得左边子数组的所有元素都比基准小,右边子数组的所有元素都比基准大,然后递归地对这两个子数组进行快速排序。
  2. 基本步骤
    • 选择基准:从数组中选择一个元素作为基准(pivot)。选择基准的方法可以有多种,例如选择第一个元素、最后一个元素、中间元素,或者随机选择一个元素。
    • 分区操作(Partitioning):重新排列数组,使得所有比基准小的元素都在基准的左边,所有比基准大的元素都在基准的右边。这个过程结束后,基准元素就处于其最终位置。
    • 递归排序:递归地对基准左边和右边的子数组进行快速排序。
    • 返回:当子数组的大小减少到1或0时,递归结束,整个数组变为有序。
  3. 复杂度:平均时间复杂度为 O(nlogn),但在最坏情况下(例如,数组已经是有序的,或者所有元素都相等)时间复杂度会退化到 O(n^2)。
  4. 示例
#include <iostream>
#include <vector>

// 交换两个元素
void swap(int* a, int* b) {
    int t = *a;
    *a = *b;
    *b = t;
}

// 选择基准并进行分区
int partition(std::vector<int>& arr, int low, int high) {
    // 选择最后一个元素作为基准
    int pivot = arr[high];
    int i = (low - 1);

    for (int j = low; j <= high - 1; j++) {
        // 如果当前元素小于或等于基准
        if (arr[j] <= pivot) {
            i++;    // 增加小于基准元素的索引
            swap(&arr[i], &arr[j]);
        }
    }
    swap(&arr[i + 1], &arr[high]);
    
    return (i + 1);
}

// 快速排序函数
void quickSort(std::vector<int>& arr, int low, int high) {
    if (low < high) {
        // pi 是分区后的基准索引,可以直接选择 (low+high)/2 位置作为分区索引
        int pi = partition(arr, low, high);

        // 分别对基准左边和右边的子数组进行快速排序
        quickSort(arr, low, pi - 1);
        quickSort(arr, pi + 1, high);
    }
}

// 打印数组
void printArray(const std::vector<int>& arr) {
    for (int num : arr) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
}

// 主函数
int main() {
    std::vector<int> arr = {10, 7, 8, 9, 1, 5};
    int n = arr.size();

    std::cout << "Original array: ";
    printArray(arr);

    quickSort(arr, 0, n - 1);

    std::cout << "Sorted array: ";
    printArray(arr);

    return 0;
}

选择排序 Selection Sort

  1. 定义:是一种简单直观的排序算法。它的工作原理是:首先在未排序的元素中找到最小(或最大)的元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(或最大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
  2. 基本步骤:
    • 从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置。
    • 从剩余未排序元素中寻找最小(或最大)元素,然后放到已排序序列的末尾。
    • 重复第二步,直到所有元素均排序完毕。
  3. 示例:
#include <iostream>
#include <vector>
#include <algorithm> // For std::swap()

void selectionSort(std::vector<int>& arr) {
    int n = arr.size();
    for (int i = 0; i < n - 1; ++i) {
        // 找到从i到数组末尾部分的最小元素的索引
        int min_idx = i;
        for (int j = i + 1; j < n; ++j) {
            if (arr[j] < arr[min_idx]) {
                min_idx = j;
            }
        }
        // 交换当前位置i和找到的最小元素的位置
        std::swap(arr[i], arr[min_idx]);
    }
}

int main() {
    std::vector<int> arr = {64, 25, 12, 22, 11};
    
    selectionSort(arr);
    
    std::cout << "Sorted array: ";
    for (int num : arr) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
    
    return 0;
}

插入排序 Insertion Sort

  1. 定义:是一种简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为新元素提供插入空间。
  2. 基本步骤
    • 从第一个元素开始,该元素可以认为已经被排序。
    • 取出下一个元素,在已经排序的元素序列中从后向前扫描。
    • 如果该元素(已排序)小于新元素,将该元素移到下一位置。
    • 重复步骤3,直到找到已排序元素小于或者等于新元素的位置。
    • 将新元素插入到该位置后。
    • 重复步骤2~5。
  3. 复杂度:时间复杂度是O(n2),在小规模数据或基本有序的数据中,插入排序可以表现得非常好,因为它的最好情况和平均情况时间复杂度分别为O(n)和O(n2)。此外,插入排序是稳定的排序算法,这意味着相等的元素之间的相对顺序不会改变。
  4. 示例
#include <iostream>
#include <vector>

void insertionSort(std::vector<int>& arr) {
    int n = arr.size();
    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 = j - 1;
        }
        // 将key插入到正确的位置
        arr[j + 1] = key;
    }
}
/* 推算
n = 5
第一次循环
for(i=1; i<5; i++>)
{
    key=arr[i]=arr[1]=5
    j=i-1 = 1-1 = 0
    while(0>=0 && 9>5){
        arr[j+1]=arr[1]=a[0]=9
        j = j-1 = -1
    }
    arr[j+1] = arr[0] = key = 5
}
第二次循环
for(i=2; i<5; i++)
{
    key = arr[i] = arr[2] = 1
    j = i-1 = 2-1 =1

    //第一次while
    while(1>=0 && arr[1]>1)
    {
        arr[j+1]=arr[2] = arr[1] = 9
        j = j-1=0
    }
    //第二次while
    while(0>=0 && arr[0] > 1)
    {
        arr[1] = arr[0] = 5
        j = j-1 = -1
    }

    arr[j+1] = arr[0] = key = 1
}
...以此类推...

*/


int main() {
    std::vector<int> arr = {9, 5, 1, 4, 3};
    insertionSort(arr);

    std::cout << "Sorted array: ";
    for (int num : arr) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

归并排序 Merge Sort

  1. 定义:是一种分治算法,其基本思想是将两个已经排序的序列合并成一个排序的序列。归并排序的效率很高,对于大数据集来说,归并排序通常比插入排序和选择排序更快。归并排序是稳定的排序算法,这意味着相等的元素之间的相对顺序不会改变。
  2. 基本步骤
    • 将当前序列分成两个等长的部分。
    • 对两个部分分别进行归并排序。
    • 将两个已排序的部分合并成一个排序的序列。
  3. 复杂度:归并排序的时间复杂度是O(n log n),其中n是数组的长度。由于归并排序需要额外的存储空间来存储临时数组,因此它的空间复杂度是O(n)。
  4. 示例
#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++;
    }
}

// l 是数组的左边界,r 是右边界
void mergeSort(std::vector<int>& arr, int left, int right) {
    if (left < right) {
        // 同 [left, mid] 和 [mid+1, right] 两个子序列
        int mid = left + (right - left) / 2;

        // 分别对两个子序列进行归并排序
        mergeSort(arr, left, mid);
        mergeSort(arr, mid + 1, right);

        // 合并两个子序列
        merge(arr, left, mid, right);
    }
}

int main() {
    std::vector<int> arr = {12, 11, 13, 5, 6};
    int arr_size = arr.size();

    mergeSort(arr, 0, arr_size - 1);

    std::cout << "Sorted array: ";
    for (int i = 0; i < arr_size; i++) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;

    return 0;
}

堆排序 Heap Sort

  1. 定义:是一种基于比较的排序算法,使用二叉堆数据结构。堆排序分为两个阶段:建立堆(Build Max Heap)和排序(Heapsort)。堆是一个满足以下性质的完全二叉树:对于最大的堆(大顶堆),父节点的键值总是大于或等于其子节点的键值;对于最小的堆(小顶堆),父节点的键值总是小于或等于其子节点的键值。
  2. 基本步骤
    • 建立最大堆:将无序序列构建成一个最大堆,即每个父节点的值都大于或等于其子节点的值。
    • 排序:交换堆顶元素(当前最大值)和数组末尾元素,然后对堆进行调整(堆化),使其满足最大堆的性质。重复这个过程,直到数组完全有序。
  3. 复杂度:堆排序的时间复杂度是O(n log n),其中n是数组的长度。堆排序是原地排序,不需要额外的存储空间,因此空间复杂度是O(1)。
  4. 示例
#include <iostream>
#include <vector>
#include <algorithm> // For std::swap()

// 调整堆,保持最大堆性质
void heapify(std::vector<int>& arr, int n, int i) {
    int largest = i;       // 初始化最大元素为根
    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;

    // 如果最大元素不是根,交换它们,并继续调整堆
    if (largest != i) {
        std::swap(arr[i], arr[largest]);
        heapify(arr, n, largest);
    }
}

// 堆排序
void heapSort(std::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--) {
        // 将当前最大元素(堆顶)与末尾元素交换
        std::swap(arr[0], arr[i]);

        // 调整堆
        heapify(arr, i, 0);
    }
}

int main() {
    std::vector<int> arr = {12, 11, 13, 5, 6};
    heapSort(arr);

    std::cout << "Sorted array: ";
    for (int num : arr) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

希尔排序 Shell Sort

  1. 定义:是插入排序的一种优化版本,也称为缩小增量排序。它的基本思想是将原始数据分成若干子序列,这些子序列中的元素之间存在一定的间隔(称为增量),对每个子序列分别进行插入排序。随着增量逐渐减小,整个序列最终变为有序序列。
  2. 基本步骤
    • 选择一个增量序列:增量序列的选择对算法的性能有很大影响。常见的增量序列有原始长度的一半、原始长度除以某个常数等。
    • 对子序列进行插入排序:以增量为间隔将原始序列分割成多个子序列,并对每个子序列进行插入排序。
    • 减小增量:减小增量的值,重复步骤2,直到增量为1,此时对整个序列进行插入排序。
  3. 复杂度:时间复杂度在平均情况下是O(n log n),但在最坏情况下是O(n^2)。希尔排序是不稳定的排序算法.
  4. 示例:
#include <iostream>
#include <vector>
#include <algorithm> // For std::swap()

// 希尔排序
void shellSort(std::vector<int>& arr) {
    int n = arr.size();
    // 增量序列,可以自定义增量序列
    std::vector<int> gaps = {1, 4, 10, 23, 57, 132, 316};
    // 也可以使用动态计算增量序列,例如:gaps[i] = n/2^i

    for (int gap : gaps) {
        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;
        }
    }
}

int main() {
    std::vector<int> arr = {12, 11, 13, 5, 6, 7, 2, 3, 4, 1};
    shellSort(arr);

    std::cout << "Sorted array: ";
    for (int num : arr) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

计数排序 Counting Sort

  1. 定义:是一种非比较型排序算法,适用于一定范围内的整数排序。它的基本思想是使用一个额外的数组来统计每个值的出现次数,然后根据这些计数来确定每个元素在排序后数组中的位置。
  2. 基本步骤:
    • 找出待排序数组中的最大值和最小值:确定排序的范围。
    • 创建计数数组:初始化计数数组,长度为最大值和最小值之差再加1。
    • 填充计数数组:遍历待排序数组,对于每个元素,增加计数数组中对应位置的计数。
    • 调整计数数组:将计数数组中的每个值调整为累积计数,这将给出每个元素在排序后数组中的位置。
    • 构建排序数组:根据调整后的计数数组构建排序后的数组。
  3. 复杂度:计数排序的时间复杂度是O(n + k),其中n是数组的长度,k是数值的范围。计数排序是稳定的排序算法,并且由于它不需要比较,所以在处理大量数据且数值范围不大时非常高效。然而,当数值范围非常大时,计数排序可能会消耗大量内存
  4. 示例:
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>

// 计数排序
void countingSort(std::vector<int>& arr) {
    int n = arr.size();
    int maxVal = *std::max_element(arr.begin(), arr.end());
    int minVal = *std::min_element(arr.begin(), arr.end());
    
    // 计数数组的大小
    int range = maxVal - minVal + 1;
    std::vector<int> count(range, 0);

    // 填充计数数组
    for (int num : arr) {
        count[num - minVal]++;
    }

    // 调整计数数组为累积计数
    for (int i = 1; i < count.size(); i++) {
        count[i] += count[i - 1];
    }

    // 构建排序数组
    std::vector<int> sortedArr(n);
    for (int num : arr) {
        sortedArr[count[num - minVal] - 1] = num;
        count[num - minVal]--;
    }

    // 将排序后的数组复制回原数组
    for (int i = 0; i < n; i++) {
        arr[i] = sortedArr[i];
    }
}

int main() {
    std::vector<int> arr = {4, 2, 2, 8, 3, 3, 1};
    countingSort(arr);

    std::cout << "Sorted array: ";
    for (int num : arr) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

桶排序 Bucket Sort

  1. 定义:是一种分布式排序算法,其基本思想是将数组分为多个“桶”,每个桶负责排序数组中的一部分数据。桶排序通常用于数据服从均匀分布的情况,它通过将数据分散到有限数量的桶里,每个桶内使用其他排序算法(如插入排序)进行排序,最后按顺序合并各个桶中的数据以得到有序的序列。
  2. 基本步骤
    • 确定桶的数量:根据数据的范围和数据个数确定桶的数量。
    • 分配数据到桶:遍历待排序数组,将每个数据分配到对应的桶中。
    • 对每个桶内的数据进行排序:通常使用插入排序或其他排序算法对桶内数据进行排序。
    • 合并桶中的数据:按顺序合并各个桶中的数据,得到最终的有序序列。
  3. 复杂度:时间复杂度取决于桶的数量和使用的排序算法,平均情况下是O(n+k),其中n是数组的长度,k是桶的数量。桶排序是稳定的排序算法,并且由于它不需要比较,所以在处理大量数据且数值范围不大时非常高效。然而,桶排序的性能依赖于数据的分布,如果数据分布不均匀,性能可能会下降.
  4. 示例:
#include <iostream>
#include <vector>
#include <algorithm>

void bucketSort(std::vector<int>& arr) {
    if (arr.empty()) {
        return;
    }

    // 找出最大值和最小值
    int maxVal = *std::max_element(arr.begin(), arr.end());
    int minVal = *std::min_element(arr.begin(), arr.end());

    // 计算桶的数量
    int bucketCount = (maxVal - minVal) / (arr.size() + 1) + 1;

    // 创建桶
    std::vector<std::vector<int>> buckets(bucketCount);

    // 分配数据到桶
    for (int num : arr) {
        int index = (num - minVal) / (arr.size() + 1);
        buckets[index].push_back(num);
    }

    // 对每个桶内的数据进行排序
    int idx = 0; // 用于结果数组的索引
    for (auto& bucket : buckets) {
        std::sort(bucket.begin(), bucket.end()); // 对每个桶进行排序
        for (int num : bucket) {
            arr[idx++] = num;
        }
    }
}

int main() {
    std::vector<int> arr = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3};
    bucketSort(arr);

    std::cout << "Sorted array: ";
    for (int num : arr) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

基数排序 Radix Sort

  1. 定义:是一种非比较型整数排序算法,其基本思想是将整数按位数切割成不同的数字,然后按每个位数分别比较。排序过程从最低位开始,依次对每一位进行排序,直到最高位排序完成。
  2. 基本步骤
    • 找到最大数:确定数组中的最大数,以确定最大位数。
    • 按位排序:从最低位到最高位,对每一位进行排序。
    • 使用稳定的排序算法:通常使用计数排序或桶排序来对每一位进行排序。
    • 合并结果:经过每一位的排序后,整个数组变为有序。
  3. 复杂度:时间复杂度是O(nk),其中n是数组的长度,k是数值的最大位数。基数排序是稳定的排序算法,并且由于它不需要比较,所以在处理大量数据且数值范围不大时非常高效。基数排序适用于整数排序,对于非整数数据,需要进行适当的转换。
  4. 示例:
#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>

// 计数排序辅助函数,对特定位数进行排序
void countSort(std::vector<int>& arr, int exp) {
    const int kMax = 10; // 0-9
    std::vector<int> output(arr.size());
    std::vector<int> count(kMax, 0);

    // 统计每个数字的出现次数
    for (int i = 0; i < arr.size(); ++i) {
        int index = (arr[i] / exp) % kMax;
        count[index]++;
    }

    // 计算累积出现次数
    for (int i = 1; i < kMax; ++i) {
        count[i] += count[i - 1];
    }

    // 填充输出数组
    for (int i = arr.size() - 1; i >= 0; --i) {
        int index = (arr[i] / exp) % kMax;
        output[count[index] - 1] = arr[i];
        count[index]--;
    }

    // 将输出数组复制回原数组
    for (int i = 0; i < arr.size(); ++i) {
        arr[i] = output[i];
    }
}

// 基数排序
void radixSort(std::vector<int>& arr) {
    // 找到最大数,确定最大位数
    int maxVal = *std::max_element(arr.begin(), arr.end());
    int exp = 1; // 从最低位开始

    while (maxVal / exp > 0) {
        countSort(arr, exp); // 对每一位进行排序
        exp *= 10; // 移动到下一位
    }
}

int main() {
    std::vector<int> arr = {170, 45, 75, 90, 802, 24, 2, 66};
    radixSort(arr);

    std::cout << "Sorted array: ";
    for (int num : arr) {
        std::cout << num << " ";
    }
    std::cout << std::endl;

    return 0;
}

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

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

相关文章

Qt学习笔记第41到50讲

第41讲 UI美化遗留问题解决 如上图所示目前记事本的雏形已现&#xff0c;但是还是有待优化&#xff0c;比如右下角的拖动问题。 解决方法&#xff1a; ①首先修改了Widget类的构造函数。 Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) {ui->s…

Linux(VMware + CentOS )设置固定ip

需求&#xff1a;设置ip为 192.168.88.130 先关闭虚拟机 启动虚拟机 查看当前自动获取的ip 使用 FinalShell 通过 ssh 服务远程登录系统&#xff0c;更换到 root 用户 修改ip配置文件 vim /etc/sysconfig/network-scripts/ifcfg-ens33 重启网卡 systemctl restart network …

CAN总线学习笔记(1、CAN总线定义)

CAN总线学习笔记&#xff08;1、CAN总线定义&#xff09; 江协科技CAN总线入门教程视频学习笔记 CAN特性 两根通信线&#xff08;CAN_H\CAN_L&#xff09;,两根线&#xff0c;无需工地 差分信号&#xff0c;抗干扰能力强 高速CAN&#xff08;ISO11898&#xff09;&#xff…

伍光和《自然地理学》电子书(含考研真题、课后习题、章节题库、模拟试题)

《自然地理学》&#xff08;第4版&#xff09;由伍光和、王乃昂、胡双熙、田连恕、张建明合著&#xff0c;于2018年11月出版。作为普通高等教育“十一五”国家级规划教材&#xff0c;本书不仅适用于高校地球科学各专业的基础课程&#xff0c;还可供环境、生态等有关科研、教学人…

Idea如何推送项目到gitee

第一步&#xff1a;先在你的gitee创建一个仓库 第二步&#xff1a; 点击推送 点击定义远程&#xff0c;将URL换成你仓库的&#xff0c;填好你的用户名和密码 可以看到已经推送到仓库了

AI笔筒操作说明及应用场景

AI笔筒由来&#xff1a; 在快节奏的现代办公环境中&#xff0c;我们一直在寻找既能提升效率、增添便利&#xff0c;又能融入企业文化、展现个人品味的桌面伙伴。为此&#xff0c;我们特推出专为追求卓越、注重细节的您设计的AI笔筒礼品版&#xff0c;它集高科技与实用性于一身…

【C++】内存管理(二):operator new/delete

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解C的operator new/delete&#xff0c;如果你觉得我写的还不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 目录 1 new/delete的底层2 new/delete的底层调用顺序3 delete[ ]调用析构函数的次数…

【工具变量】中国制造2025试点城市数据集(2000-2023年)

数据简介&#xff1a;《中国制造2025》是中国ZF于2015年5月8日印发的一项战略规划&#xff0c;旨在加快制造业的转型升级&#xff0c;提升制造业的质量和效益&#xff0c;实现从制造大国向制造强国的转变。该规划是中国实施制造强国战略的第一个十年行动纲领&#xff0c;明确提…

小菜家教平台(一):基于SpringBoot+Vue打造一站式学习管理系统

前言 现在已经学习了很多与Java相关的知识&#xff0c;但是迟迟没有进行一个完整的实践&#xff08;之前这个项目开发到一半&#xff0c;很多东西没学搁置了&#xff0c;同时原先的项目中也有很多的问题&#xff09;&#xff0c;所以现在准备从零开始做一个基于SpringBootVue的…

算法专题:字符串

目录 1. 最长公共前缀 1.1 算法原理 1.2 算法代码 2. 最长回文子串 2.1 算法原理 2.2 算法代码 3. 二进制求和 3.1 算法原理 3.2 算法代码 4. 字符串相乘 4.1 算法原理 4.2 算法代码 1. 最长公共前缀 . - 力扣&#xff08;LeetCode&#xff09; 1.1 算法原理 有以…

非线性数据结构之图

一、有向图&#xff08;Directed Graph&#xff09; 1. 定义 有向图是一个由顶点&#xff08;节点&#xff09;和有方向的边&#xff08;弧&#xff09;组成的图。在有向图中&#xff0c;每条边都有一个起点和一个终点&#xff0c;表示从一个顶点到另一个顶点的关系。 2. 特…

虚拟现实技术课程开发思路

文章目录 组队选题立项分工建模说明&#xff1a;场景说明&#xff1a;交互说明&#xff1a; 结语&#xff1a; 前言&#xff1a;最近学弟学妹们反馈水水老师课程开始上强度了。不仅有翻转课堂&#xff0c;还有理论课实验课都要做东西出来。听说理论课是做什么博物馆什么的&…

FPGA视频GTH 8b/10b编解码转PCIE3.0传输,基于XDMA中断架构,提供工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐我已有的PCIE方案我已有的 GT 高速接口解决方案 3、PCIE基础知识扫描4、工程详细设计方案工程设计原理框图输入Sensor之-->芯片解码的HDMI视频数据组包基于GTH高速接口的视频传输架构GTH IP 简介GTH 基本结构GTH 发送和接收处理…

CSS中常见的两列布局、三列布局、百分比和多行多列布局!

目录 一、两列布局 1、前言&#xff1a; 2. 两列布局的常见用法 两列布局的元素示例&#xff1a; 代码运行后如下&#xff1a; 二、三列布局 1.前言 2. 三列布局的常见用法 三列布局的元素示例&#xff1a; 代码运行后如下&#xff1a; 三、多行多列 1.前言 2&…

jmeter结合ansible分布式压测--1数据准备

一、搭建ansible环境 ansible是基于python开发&#xff0c;通过ssh连接客户机执行任务。ansible可以批量系统配置、批量程序部署、批量运行命令等。 1、安装yum install ansible 2、检查ansible的版本:ansible --version 二、利用ansible在其他机器上准备压测数据 1、本地准…

蓬勃发展:移动开发——关于软件开发你需要知道些什么

一、前言 移动开发一直都是软件开发领域中最有趣的领域之一&#xff0c;这是因为&#xff1a; 1、移动开发为“只有一个人”的开发团队提供了一个非常独特的机会&#xff0c;让他可以在相对较短的时间内建立一个实际的、可用的、有意义的应用程序&#xff1b; 2、移动开发也代…

gitmakegdb

git git reset 命令 | 菜鸟教程 (runoob.com) 像嫁接一样 make Makefile | 爱编程的大丙 (subingwen.cn) # 举例: 有源文件 a.c b.c c.c head.h, 需要生成可执行程序 app ################# 例1 ################# app:a.c b.c c.cgcc a.c b.c c.c -o app################# 例…

网络安全认证的证书有哪些?

在网络安全领域&#xff0c;专业认证不仅是个人技术能力的象征&#xff0c;也是职业发展的重要推动力。随着网络安全威胁的日益严峻&#xff0c;对网络安全专业人才的需求也在不断增长。本文将介绍一些网络安全认证的证书&#xff0c;帮助有志于从事网络安全行业的人士了解并选…

初阶数据结构的各种排序方法——冒泡,直接插入,希尔,快排,选择,归并(C语言)

1.交换排序 交换排序基本思想&#xff1a; 所谓交换&#xff0c;就是根据序列中两个记录键值的⽐较结果来对换这两个记录在序列中的位置 交换排序的特点是&#xff1a;将键值较⼤的记录向序列的尾部移动&#xff0c;键值较⼩的记录向序列的前部移动。 1.1冒泡排序 例子&…

qt QFileInfo详解

1、概述 QFileInfo是Qt框架中用于获取文件信息的工具类。它提供了与操作系统无关的文件属性&#xff0c;如文件的名称、位置&#xff08;路径&#xff09;、访问权限、类型&#xff08;是否为目录或符号链接&#xff09;等。此外&#xff0c;QFileInfo还可以获取文件的大小、创…