C++排序算法全解析

常见排序算法详解(C++实现)

排序算法是计算机科学中的基础技术,用于将数据序列按特定顺序(如升序或降序)排列。常见算法包括冒泡排序、选择排序、插入排序、快速排序、归并排序和堆排序等。每种算法都有其原理、时间复杂度和适用场景。本文将逐一介绍这些算法,并提供C++代码实现,帮助你直观理解。

1. 冒泡排序(Bubble Sort)

冒泡排序通过重复比较相邻元素并交换顺序错误的元素,将最大元素逐渐"冒泡"到末尾。

  • 原理:从数组开头开始,比较相邻元素,如果顺序错误则交换。重复此过程直到数组有序。
  • 时间复杂度:平均和最坏情况为O(n\^2),最好情况(已有序)为O(n)
  • C++代码
cpp 复制代码
void bubbleSort(int arr[], int n) {
    for (int i = 0; i < n-1; i++) {
        for (int j = 0; j < n-i-1; j++) {
            if (arr[j] > arr[j+1]) {
                std::swap(arr[j], arr[j+1]);
            }
        }
    }
}
2. 选择排序(Selection Sort)

选择排序通过重复选择未排序部分的最小元素,并将其放到已排序部分的末尾。

  • 原理:遍历数组,找到最小元素,与当前位置交换。重复此过程直到数组有序。
  • 时间复杂度:平均、最坏和最好情况均为O(n\^2)
  • C++代码
cpp 复制代码
void selectionSort(int arr[], int n) {
    for (int i = 0; i < n-1; i++) {
        int min_idx = i;
        for (int j = i+1; j < n; j++) {
            if (arr[j] < arr[min_idx]) {
                min_idx = j;
            }
        }
        std::swap(arr[i], arr[min_idx]);
    }
}
3. 插入排序(Insertion Sort)

插入排序通过构建有序序列,对未排序元素逐个插入到正确位置。

  • 原理:从第二个元素开始,将其与已排序部分比较,插入到合适位置。
  • 时间复杂度:平均和最坏情况为O(n\^2),最好情况(已有序)为O(n)
  • C++代码
cpp 复制代码
void insertionSort(int arr[], int n) {
    for (int i = 1; i < n; i++) {
        int key = arr[i];
        int j = i-1;
        while (j >= 0 && arr[j] > key) {
            arr[j+1] = arr[j];
            j--;
        }
        arr[j+1] = key;
    }
}
4. 快速排序(Quick Sort)

快速排序通过分治法选择基准元素,将数组分为小于基准和大于基准的两部分,递归排序。

  • 原理:选择基准(如第一个元素),分区后递归排序子数组。
  • 时间复杂度:平均和最好情况为O(n \\log n),最坏情况(已有序)为O(n\^2)
  • C++代码
cpp 复制代码
int partition(int arr[], int low, int high) {
    int pivot = arr[low];
    int i = low, j = high;
    while (i < j) {
        while (i < j && arr[j] >= pivot) j--;
        if (i < j) arr[i++] = arr[j];
        while (i < j && arr[i] <= pivot) i++;
        if (i < j) arr[j--] = arr[i];
    }
    arr[i] = pivot;
    return i;
}

void quickSort(int arr[], int low, int high) {
    if (low < high) {
        int pi = partition(arr, low, high);
        quickSort(arr, low, pi-1);
        quickSort(arr, pi+1, high);
    }
}
5. 归并排序(Merge Sort)

归并排序使用分治法将数组分成两半,递归排序后合并。

  • 原理:递归分割数组到最小单位,然后合并两个有序数组。
  • 时间复杂度:平均、最坏和最好情况均为O(n \\log n)
  • C++代码
cpp 复制代码
void merge(int arr[], int left, int mid, int right) {
    int n1 = mid - left + 1;
    int n2 = right - mid;
    int L[n1], R[n2];
    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];
    int i = 0, j = 0, k = left;
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) arr[k++] = L[i++];
        else arr[k++] = R[j++];
    }
    while (i < n1) arr[k++] = L[i++];
    while (j < n2) arr[k++] = R[j++];
}

void mergeSort(int arr[], int left, int right) {
    if (left < right) {
        int mid = left + (right - left) / 2;
        mergeSort(arr, left, mid);
        mergeSort(arr, mid+1, right);
        merge(arr, left, mid, right);
    }
}
6. 堆排序(Heap Sort)

堆排序利用堆数据结构,将数组视为最大堆,重复提取最大元素并调整堆。

  • 原理:构建最大堆,交换根节点与末尾元素,调整堆大小并重复。
  • 时间复杂度:平均、最坏和最好情况均为O(n \\log n)
  • C++代码
cpp 复制代码
void heapify(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(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--) {
        std::swap(arr[0], arr[i]);
        heapify(arr, i, 0);
    }
}

总结

常见排序算法各有特点:

  • 时间复杂度比较
    • O(n\^2)算法:冒泡、选择、插入排序,简单但效率低,适合小规模数据。
    • O(n \\log n)算法:快速、归并、堆排序,高效,适合大规模数据。
  • 稳定性:冒泡、插入、归并排序是稳定的(相等元素顺序不变);选择、快速、堆排序不稳定。
  • 空间复杂度:冒泡、选择、插入、堆排序为O(1);快速排序平均O(\\log n)(递归栈);归并排序为O(n)

在实际应用中,选择算法需考虑数据规模、内存限制和稳定性需求。例如,快速排序在平均情况下性能优异,而归并排序适合外部排序。通过以上C++代码,你可以动手实现并加深理解。

相关推荐
胡萝卜不甜9 小时前
算法宗门---迪杰斯特拉Dijkstra(最短路径算法)
算法
BD_Marathon9 小时前
SpringBoot程序快速启动
java·spring boot·后端
stillaliveQEJ9 小时前
【JavaEE】Spring IoC(二)
java·开发语言·spring
练习时长一年9 小时前
LeetCode热题100(爬楼梯)
算法·leetcode·职场和发展
寻星探路9 小时前
【Python 全栈测开之路】Python 基础语法精讲(一):常量、变量与运算符
java·开发语言·c++·python·http·ai·c#
ohoy9 小时前
RedisTemplate 使用之List
数据结构·windows·list
朔北之忘 Clancy9 小时前
2020 年 6 月青少年软编等考 C 语言一级真题解析
c语言·开发语言·c++·学习·算法·青少年编程·题解
_codemonster9 小时前
计算机视觉入门到实战系列(九) SIFT算法(尺度空间、极值点判断)
深度学习·算法·计算机视觉
行百里er9 小时前
代码跑得慢?让Spring的StopWatch告诉你真相!
java·后端·github