当前位置: 首页 > backend >正文

常见排序算法及复杂度分析

冒泡排序 (Bubble Sort)

基本思想

  • 相邻元素比较,大的元素后移
  • 每轮将最大元素"冒泡"到末尾

代码实现

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]) {swap(arr[j], arr[j+1]);}}}}

复杂度分析

  • 时间复杂度:O(n²)
  • 空间复杂度:O(1)
  • 稳定性:稳定
  • 最好情况:O(n)
  • 最坏情况:O(n²)

2. 选择排序 (Selection Sort)

基本思想

  • 每次从未排序区域选择最小元素
  • 放到已排序区域末尾

代码实现

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;}}swap(arr[i], arr[min_idx]);}}

复杂度分析

  • 时间复杂度:O(n²)
  • 空间复杂度:O(1)
  • 稳定性:不稳定
  • 最好情况:O(n²)
  • 最坏情况:O(n²)

3. 插入排序 (Insertion Sort)

基本思想

  • 将元素插入到已排序区域的合适位置
  • 适合小数据量或基本有序数据

代码实现

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;}}

复杂度分析

  • 时间复杂度:O(n²)
  • 空间复杂度:O(1)
  • 稳定性:稳定
  • 最好情况:O(n)
  • 最坏情况:O(n²)

4. 快速排序 (Quick Sort)

基本思想

  • 选择基准元素
  • 将小于基准的元素放在左边
  • 将大于基准的元素放在右边
  • 递归处理左右两部分

代码实现

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);}}

复杂度分析

  • 时间复杂度:平均O(nlogn)
  • 空间复杂度:O(logn)
  • 稳定性:不稳定
  • 最好情况:O(nlogn)
  • 最坏情况:O(n²)

5. 归并排序 (Merge Sort)

基本思想

  • 将数组分成两半
  • 递归排序两半
  • 合并两个有序数组

代码实现

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);}}

复杂度分析

  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(n)
  • 稳定性:稳定
  • 最好情况:O(nlogn)
  • 最坏情况:O(nlogn)

6. 堆排序 (Heap Sort)

基本思想

  • 构建最大堆
  • 将堆顶元素与末尾元素交换
  • 重新调整堆

代码实现

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);}}

复杂度分析

  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(1)
  • 稳定性:不稳定
  • 最好情况:O(nlogn)
  • 最坏情况:O(nlogn)

7. 希尔排序 (Shell Sort)

基本思想

  • 是插入排序的改进版
  • 通过不同的间隔序列进行分组插入排序

代码实现

void shellSort(int arr[], int n) {for (int gap = n/2; gap > 0; gap /= 2) {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;}}}

复杂度分析

  • 时间复杂度:取决于间隔序列,平均O(n^1.3)
  • 空间复杂度:O(1)
  • 稳定性:不稳定
  • 最好情况:O(n)
  • 最坏情况:O(n²)

8. 计数排序 (Counting Sort)

基本思想

  • 统计每个元素出现的次数
  • 根据统计结果重建数组

代码实现

void countingSort(int arr[], int n) {int max = arr[0];for (int i = 1; i < n; i++)if (arr[i] > max)max = arr[i];int count[max+1] = {0};for (int i = 0; i < n; i++)count[arr[i]]++;int index = 0;for (int i = 0; i <= max; i++)while (count[i]--)arr[index++] = i;}

复杂度分析

  • 时间复杂度:O(n+k),k为数据范围
  • 空间复杂度:O(k)
  • 稳定性:稳定
  • 最好情况:O(n+k)
  • 最坏情况:O(n+k)

9. 基数排序 (Radix Sort)

基本思想

  • 按照位数进行排序
  • 从最低位到最高位依次排序

代码实现

void radixSort(int arr[], int n) {int max = arr[0];for (int i = 1; i < n; i++)if (arr[i] > max)max = arr[i];for (int exp = 1; max/exp > 0; exp *= 10)countSort(arr, n, exp);}

复杂度分析

  • 时间复杂度:O(d(n+k)),d为位数
  • 空间复杂度:O(n+k)
  • 稳定性:稳定
  • 最好情况:O(d(n+k))
  • 最坏情况:O(d(n+k))

10. 排序算法比较表

| 排序算法 | 平均时间复杂度 | 最好情况 | 最坏情况 | 空间复杂度 | 稳定性 |

|:--------:|:--------------:|:--------:|:--------:|:----------:|:------:|

| 冒泡排序 | O(n²) | O(n) | O(n²) | O(1) | 稳定 |

| 选择排序 | O(n²) | O(n²) | O(n²) | O(1) | 不稳定 |

| 插入排序 | O(n²) | O(n) | O(n²) | O(1) | 稳定 |

| 快速排序 | O(nlogn) | O(nlogn) | O(n²) | O(logn) | 不稳定 |

| 归并排序 | O(nlogn) | O(nlogn) | O(nlogn) | O(n) | 稳定 |

| 堆排序 | O(nlogn) | O(nlogn) | O(nlogn) | O(1) | 不稳定 |

| 希尔排序 | O(n^1.3) | O(n) | O(n²) | O(1) | 不稳定 |

| 计数排序 | O(n+k) | O(n+k) | O(n+k) | O(k) | 稳定 |

| 基数排序 | O(d(n+k)) | O(d(n+k)) | O(d(n+k)) | O(n+k) | 稳定 |

11. 选择建议

  1. 小数据量(n < 50):
  • 插入排序
  • 冒泡排序
  • 选择排序
  1. 中等数据量(50 < n < 1000):
  • 快速排序
  • 归并排序
  • 堆排序
  1. 大数据量(n > 1000):
  • 快速排序
  • 归并排序
  • 堆排序
  1. 特殊场景:
  • 需要稳定性:归并排序
  • 数据范围小:计数排序
  • 字符串排序:基数排序
  • 内存受限:堆排序
http://www.xdnf.cn/news/5923.html

相关文章:

  • 贪吃蛇游戏排行榜模块开发总结:从数据到视觉的实现
  • 在企业级智能体浪潮中,商业数据分析之王SAS或将王者归来
  • 数睿通2.0数据中台,已购买源代码
  • 汽车传动系统设计:原理、挑战与创新路径
  • Supabase 的入门详细介绍
  • X1A000171000300,FC2012AN,32.768kHz,2012mm,EPSON晶振
  • 描述性统计工具 - AxureMost 落葵网
  • BGP-路由属性2
  • HTML应用指南:利用POST请求获取全国京东快递服务网点位置信息
  • Kubernetes容器运行时:Containerd vs Docker
  • 涌现理论:连接万物的神秘力量
  • 【MySQL】函数
  • Leetcode 3543. Maximum Weighted K-Edge Path
  • library和配置管理
  • 2025年真实面试问题汇总(二)
  • 窄带卫星通信技术突破:海聊卫通双算法免费开放推动行业变革
  • Web Service及其实现技术(SOAP、REST、XML-RPC)介绍
  • 亚马逊云科技:引领数字时代的云服务先锋
  • 我们来学nacos -- 集群nacos2.5.1mysql8.4
  • RDMA网络通信技术、NCCL集合通讯(GPU)
  • 数字IC后端实现教程 | Early Clock Flow和Useful skew完全不是一个东西
  • 4. 文字效果/2D-3D转换 - 3D翻转卡片
  • 使用docker安装clickhouse集群
  • Kotlin 中的作用域函数
  • JavaEE--初识网络
  • WebGIS开发面试题:前端篇(五)
  • SPL做量化---TRIX 三重指数平滑平均线
  • 《100天精通Python——基础篇 2025 第18天:正则表达式入门实战,解锁字符串处理的魔法力量》
  • RTSP有两套格式吗?
  • NLTK进行文本分类和词性标注