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++代码,你可以动手实现并加深理解。

相关推荐
m0_587383001 小时前
广州 24 小时自助健身房解决方案技术实现与实战指南
java·spring·小程序·架构·需求分析
mmmmath_31 小时前
LeetCode.199.二叉树的右视图
数据结构·leetcode
·云扬·1 小时前
Prompt 工程与安全:从 System 设计到注入防御
java·人工智能·安全·ai·prompt
专注仿真1 小时前
引擎扩展性与集成设计深度剖析:从 14 个扩展点到 DIS→HLA 演进之路
开发语言·算法·仿真引擎·推演引擎
码爸1 小时前
支持向量机介绍与示例
算法·机器学习·支持向量机
怕浪猫2 小时前
2028编程圈很火的10个Skills
算法·面试·github
代码不停2 小时前
自动化测试(java)
java·开发语言·selenium·自动化
鬼手点金4 小时前
opencode-rules 插件
java·开发语言·前端·人工智能·chrome·git·github
paopaokaka_luck5 小时前
滑雪场管理系统(AI智能助手流式对话,ECharts 运营数据分析、教练、雪具与场地一体化预约,钱包支付退款、订单核销与服务评价)
java·人工智能·spring boot·网络协议·数据分析·echarts
Wang's Blog5 小时前
Java 项目实战: 交友项目 - Dubbo 的内部结构与一次调用的完整链路
java·dubbo