• c++排序算法


    冒泡排序

    1. //冒泡 通过多次交换相邻元素将较大(或较小)的元素逐渐 "浮" 到数组的一端。该算法的时间复杂度为 O(N^2)。
    2. void bubbleSort(vector<int>&arr) {
    3. int n=arr.size();
    4. for(int i=0; i-1; i++) {
    5. for(int j=0; j-1; j++) {
    6. if(arr[j]>arr[j+1]) {
    7. swap(arr[j],arr[j+1]);
    8. }
    9. }
    10. }
    11. }

    两层循环,一次次比较交换。

    选择排序

    1. //选择排序 在每次迭代中选择未排序部分的最小(或最大)元素,并将其放在已排序部分的末尾。时间复杂度为 O(N^2)。
    2. void selectionSort(std::vector<int>& arr) {
    3. int n = arr.size();
    4. for(int i=0; i
    5. int minIndex=i;
    6. for(int j=i+1; j//找未排序部分的最小值对应的index
    7. if(arr[j]
    8. minIndex=j;
    9. }
    10. }
    11. //找到未排序部分的最小值之后,需要放在有序部分的末尾,也就是i位置.所以交换.
    12. swap(arr[i],arr[minIndex]);
    13. }
    14. }

    在未排序部分选一个最小的放到有序部分末尾。

    插入排序

    1. //插入排序 将未排序部分的元素逐个插入到已排序部分的正确位置。时间复杂度为 O(N^2),但对于小型数据集或部分已排序的数据,插入排序具有较好的性能。
    2. void insertionSort(std::vector<int>& arr) {
    3. int n = arr.size();
    4. for (int i = 1; i < n; ++i) {
    5. int key = arr[i];
    6. int j = i - 1;
    7. while (j >= 0 && arr[j] > key) {
    8. arr[j + 1] = arr[j];
    9. --j;
    10. }
    11. arr[j+1]=key;
    12. }
    13. }

    从未排序部分取一个插入到有序部分。

    快速排序

    1. //快速排序(Quick Sort):也是采用分治策略的排序算法,通过选择一个基准值,将数据分为小于基准值和大于基准值的两部分,然后递归地对这两部分进行排序。时间复杂度为 O(NlogN),具有较好的性能。
    2. // 将数组以升序进行排列!
    3. // 分区操作函数,将数组分成两个部分并返回基准元素的最终位置
    4. void quickSort(vector<int> &nums, int l, int r) {
    5. if (l + 1 >= r) {
    6. return;
    7. }
    8. int first = l, last = r - 1, key = nums[first];
    9. while (first < last) {
    10. while(first < last && nums[last] > key) {
    11. --last;
    12. }//从右往左找小于基枢的值
    13. nums[first] = nums[last];
    14. //把小于基枢的值赋给左边.
    15. while (first < last && nums[first] < key) {
    16. ++first;
    17. }//从左往右找大于基枢的值
    18. nums[last] = nums[first]; //找到之后把这个大于基枢的值再赋给右边.
    19. }//这样循环下去,first指向的位置最终左边都是小于基枢,右边都是大于基枢. first=last把基枢位置确定下来.
    20. nums[first] = key;
    21. quickSort(nums, l, first);
    22. quickSort(nums, first + 1, r);
    23. }

    分支法,先分区,找到分区的位置后,两边继续

    quickSort(nums, l, first);
    quickSort(nums, first + 1, r);

    首先设置第一个为基枢。从右往左找比基枢小的值,然后复制到first,接着从first向右找第一个比基枢大的值,复制到fast位置,然后fast往左找小的,再给first赋值,直到first和last相等,此次,基枢位置确定,把最开始设置的基枢赋值过来。基枢位置确定之后,就有了左右分区。在左右分区继续快排。

    归并排序

    1. //归并排序
    2. void merge_sort(vector<int> &nums, int l, int r, vector<int> &temp) {
    3. if (l + 1 >= r) {
    4. return;
    5. }
    6. // divide
    7. int m = l + (r - l) / 2;
    8. merge_sort(nums, l, m, temp);
    9. merge_sort(nums, m, r, temp);
    10. // conquer
    11. int p = l, q = m, i = l;
    12. while (p < m || q < r) {
    13. if (q >= r || (p < m && nums[p] <= nums[q])) {
    14. temp[i++] = nums[p++];
    15. } else {
    16. temp[i++] = nums[q++];
    17. }
    18. }
    19. for (i = l; i < r; ++i) {
    20. nums[i] = temp[i];
    21. }
    22. }

    在合并过程中,我们使用双指针 pq 分别指向左右两个子数组的起始位置,然后比较指针位置处的元素大小,将较小的元素放入临时数组 temp 中。最后,将临时数组中的元素复制回原数组。

    1. int main() {
    2. std::vector<int> numbers = {5, 2, 8, 1, 3};
    3. // std::sort(numbers.begin(), numbers.end());
    4. //快排 std::sort:使用快速排序(Quick Sort)实现的排序算法,平均时间复杂度为 O(NlogN)
    5. // std::stable_sort(numbers.begin(), numbers.end());
    6. //std::stable_sort:使用归并排序(Merge Sort)实现的排序算法,保持相等元素的相对顺序。时间复杂度为 O(NlogN)
    7. // bubbleSort(numbers);//冒泡排序的平均时间复杂度为 O(N^2)
    8. // selectionSort(numbers);//选择排序的时间复杂度为 O(N^2)
    9. // insertionSort(numbers);//插入排序的时间复杂度为 O(N^2)
    10. // quickSort(numbers,0,numbers.size());
    11. vector<int> temp(numbers.size());
    12. merge_sort(numbers, 0, numbers.size(), temp);
    13. std::cout << "Sorted numbers: ";
    14. for (int num : numbers) {
    15. std::cout << num << " ";
    16. }
    17. std::cout << std::endl;
    18. return 0;
    19. }

    是否稳定

    1. 稳定的排序算法

      • 冒泡排序(Bubble Sort)
      • 插入排序(Insertion Sort)
      • 归并排序(Merge Sort)
      • 基数排序(Radix Sort)
    2. 不稳定的排序算法

      • 选择排序(Selection Sort)
      • 快速排序(Quick Sort)
      • 堆排序(Heap Sort)
      • 希尔排序(Shell Sort)

    时间复杂度

    • 冒泡排序、插入排序、选择排序的时间复杂度为 O(n^2)。
    • 归并排序、快速排序、堆排序的平均时间复杂度为 O(n log n)。
    • 基数排序的时间复杂度为 O(d * (n + k))

    空间复杂度

    空间复杂度是指算法在运行过程中所需要的额外的存储空间大小。以下是几种常见排序算法的空间复杂度:

    1. 冒泡排序(Bubble Sort):空间复杂度为 O(1),因为只需要常数级别的额外空间用于交换元素。

    2. 插入排序(Insertion Sort):空间复杂度为 O(1),因为只需要常数级别的额外空间用于交换元素。

    3. 选择排序(Selection Sort):空间复杂度为 O(1),因为只需要常数级别的额外空间用于交换元素。

    4. 归并排序(Merge Sort):归并排序是一种分治算法,在归并过程中需要额外的空间来存储临时数组,所以空间复杂度为 O(n)。

    5. 快速排序(Quick Sort):快速排序是一种原地排序算法,通常不需要额外的空间,但是如果使用递归实现,则需要系统栈来存储递归调用的上下文,因此空间复杂度在最坏情况下可能达到 O(n),平均情况下为 O(log n)。

    6. 堆排序(Heap Sort):堆排序是一种原地排序算法,不需要额外的空间,因此空间复杂度为 O(1)。

    7. 希尔排序(Shell Sort):希尔排序是一种改进的插入排序算法,空间复杂度取决于间隔序列的选择,一般为 O(1) 到 O(n)。

    8. 基数排序(Radix Sort):基数排序需要额外的空间来存储桶,空间复杂度取决于数据的范围和位数,一般为 O(n + k),其中 n 是数组长度,k 是数据的范围。

  • 相关阅读:
    计算机网络第六章——应用层(下)
    thonny的汉字编码是UTF-8,如何才能转为GB2312?
    从“交易核心”到“数据核心”,国产数据库要换道超车丨数据猿专访
    【Javascript】数组的基本操作
    【FPGA项目】沙盘演练——基础版报文收发
    mysql检查表、分析表、优化表
    如何入门网络安全有什么条件呢?持有NISP或CISP证书可敲门
    【数据分享】厦门市共享单车数据
    美格智能Cat.1蜂窝IPC解决方案 助力安防监控智慧连接
    java计算机毕业设计springboot+vue超时代停车场管理平台系统(源码+系统+mysql数据库+Lw文档)
  • 原文地址:https://blog.csdn.net/hyf1712011164/article/details/136731701