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

Java实现10大经典排序算法

       本文简明介绍了10种经典排序算法,涵盖冒泡、选择、插入、快速、希尔、归并、堆、计数、桶和基数排序。每种算法从定义、时间复杂度(最佳/平均/最差)、空间复杂度、稳定性及适用场景进行说明,并附Java实现代码。关键对比显示:快速排序适合通用场景(平均O(nlogn)),堆排序保证最坏情况性能,归并排序兼顾稳定性和效率,而计数/桶/基数排序适用于特定数据特征。最后给出选择建议:内存敏感用堆排序,需稳定性选归并,特定数据用非比较类算法。

时间复杂度和空间复杂度入门必备知识点-CSDN博客 

目录

1. 冒泡排序 (Bubble Sort)

2. 选择排序 (Selection Sort)

3. 插入排序 (Insertion Sort)

4. 快速排序 (Quick Sort)

5. 希尔排序 (Shell Sort)

6. 归并排序 (Merge Sort)

7. 堆排序 (Heap Sort)

8. 计数排序 (Counting Sort)

9. 桶排序 (Bucket Sort)

10. 基数排序 (Radix Sort)

十大排序算法对比总结


1. 冒泡排序 (Bubble Sort)

  • 定义:重复遍历数组,比较相邻元素,若顺序错误则交换。每轮遍历将最大元素“冒泡”到末尾。

  • 时间复杂度

    • 最好:O(n)(已有序)

    • 平均:O(n²)

    • 最坏:O(n²)(完全逆序)

  • 空间复杂度:O(1)(原地排序)

  • 稳定性:稳定

  • Java代码

    public void bubbleSort(int[] arr) {int n = arr.length;for (int i = 0; i < n - 1; i++) {for (int j = 0; j < n - i - 1; j++) {if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}
    }

2. 选择排序 (Selection Sort)

  • 定义:遍历数组,每次选择最小元素放到已排序序列末尾。

  • 时间复杂度:O(n²)(所有情况)

  • 空间复杂度:O(1)(原地排序)

  • 稳定性:不稳定(交换可能破坏顺序)

  • Java代码

    public void selectionSort(int[] arr) {int n = arr.length;for (int i = 0; i < n - 1; i++) {int minIdx = i;for (int j = i + 1; j < n; j++) {if (arr[j] < arr[minIdx]) minIdx = j;}int temp = arr[i];arr[i] = arr[minIdx];arr[minIdx] = temp;}
    }

3. 插入排序 (Insertion Sort)

  • 定义:将未排序元素插入已排序序列的合适位置。

  • 时间复杂度

    • 最好:O(n)(已有序)

    • 平均/最坏:O(n²)

  • 空间复杂度:O(1)(原地排序)

  • 稳定性:稳定

  • Java代码

    public void insertionSort(int[] arr) {int n = arr.length;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²)(基准选择不当)

  • 空间复杂度:O(log n)(递归栈)

  • 稳定性:不稳定

  • Java代码

    public 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);}
    }private int partition(int[] arr, int low, int high) {int pivot = arr[high];int i = low - 1;for (int j = low; j < high; j++) {if (arr[j] < pivot) {i++;int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}int temp = arr[i + 1];arr[i + 1] = arr[high];arr[high] = temp;return i + 1;
    }

5. 希尔排序 (Shell Sort)

  • 定义:改进的插入排序,按增量分组排序,逐渐减小增量至1。

  • 时间复杂度:O(n log n) ~ O(n²)(取决于增量序列)

  • 空间复杂度:O(1)(原地排序)

  • 稳定性:不稳定

  • Java代码

    public void shellSort(int[] arr) {int n = arr.length;for (int gap = n / 2; gap > 0; gap /= 2) {for (int i = gap; i < n; i++) {int temp = arr[i];int j = i;while (j >= gap && arr[j - gap] > temp) {arr[j] = arr[j - gap];j -= gap;}arr[j] = temp;}}
    }

6. 归并排序 (Merge Sort)

  • 定义:分治法思想。递归拆分数组为两半,排序后合并。

  • 时间复杂度:O(n log n)(所有情况)

  • 空间复杂度:O(n)(合并需额外空间)

  • 稳定性:稳定

  • Java代码

    public void mergeSort(int[] arr, int left, int right) {if (left < right) {int mid = (left + right) / 2;mergeSort(arr, left, mid);mergeSort(arr, mid + 1, right);merge(arr, left, mid, right);}
    }private void merge(int[] arr, int left, int mid, int right) {int[] temp = new int[right - left + 1];int i = left, j = mid + 1, k = 0;while (i <= mid && j <= right) {if (arr[i] <= arr[j]) temp[k++] = arr[i++];else temp[k++] = arr[j++];}while (i <= mid) temp[k++] = arr[i++];while (j <= right) temp[k++] = arr[j++];System.arraycopy(temp, 0, arr, left, temp.length);
    }

7. 堆排序 (Heap Sort)

  • 定义:构建最大堆,将堆顶元素(最大值)与末尾交换,调整堆。

  • 时间复杂度:O(n log n)(所有情况)

  • 空间复杂度:O(1)(原地排序)

  • 稳定性:不稳定

  • Java代码

    public void heapSort(int[] arr) {int n = arr.length;for (int i = n / 2 - 1; i >= 0; i--) heapify(arr, n, i);for (int i = n - 1; i > 0; i--) {int temp = arr[0];arr[0] = arr[i];arr[i] = temp;heapify(arr, i, 0);}
    }private void heapify(int[] arr, int n, int i) {int largest = i, left = 2 * i + 1, 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) {int swap = arr[i];arr[i] = arr[largest];arr[largest] = swap;heapify(arr, n, largest);}
    }

8. 计数排序 (Counting Sort)

  • 定义:统计元素出现次数,按计数重建有序数组。

  • 时间复杂度:O(n + k)(k为数据范围)

  • 空间复杂度:O(n + k)(需额外空间)

  • 稳定性:稳定(需反向填充)

  • 适用场景:整数且范围小

  • Java代码

    public void countingSort(int[] arr) {int max = Arrays.stream(arr).max().getAsInt();int min = Arrays.stream(arr).min().getAsInt();int range = max - min + 1;int[] count = new int[range];int[] output = new int[arr.length];for (int num : arr) count[num - min]++;for (int i = 1; i < range; i++) count[i] += count[i - 1];for (int i = arr.length - 1; i >= 0; i--) {output[count[arr[i] - min] - 1] = arr[i];count[arr[i] - min]--;}System.arraycopy(output, 0, arr, 0, arr.length);
    }

9. 桶排序 (Bucket Sort)

  • 定义:将数据分到有限数量的桶中,每个桶单独排序(通常用插入排序)。

  • 时间复杂度

    • 最好:O(n)(均匀分布)

    • 平均:O(n + k)(k为桶数)

    • 最坏:O(n²)(所有元素入一个桶)

  • 空间复杂度:O(n + k)

  • 稳定性:稳定(取决于桶内排序)

  • 适用场景:数据均匀分布

  • Java代码

    public void bucketSort(float[] arr) {int n = arr.length;ArrayList<Float>[] buckets = new ArrayList[n];for (int i = 0; i < n; i++) buckets[i] = new ArrayList<>();for (float num : arr) {int idx = (int) (num * n);buckets[idx].add(num);}for (ArrayList<Float> bucket : buckets) Collections.sort(bucket);int idx = 0;for (ArrayList<Float> bucket : buckets) for (float num : bucket) arr[idx++] = num;
    }

10. 基数排序 (Radix Sort)

  • 定义:按位数从低位到高位依次排序(通常用计数排序作为子排序)。

  • 时间复杂度:O(d(n + k))(d为最大位数,k为基数)

  • 空间复杂度:O(n + k)(需额外空间)

  • 稳定性:稳定

  • 适用场景:整数或字符串

  • Java代码

    public void radixSort(int[] arr) {int max = Arrays.stream(arr).max().getAsInt();for (int exp = 1; max / exp > 0; exp *= 10) countingSortByDigit(arr, exp);
    }private void countingSortByDigit(int[] arr, int exp) {int n = arr.length;int[] output = new int[n];int[] count = new int[10];for (int num : arr) count[(num / exp) % 10]++;for (int i = 1; i < 10; i++) count[i] += count[i - 1];for (int i = n - 1; i >= 0; i--) {output[count[(arr[i] / exp) % 10] - 1] = arr[i];count[(arr[i] / exp) % 10]--;}System.arraycopy(output, 0, arr, 0, n);
    }

十大排序算法对比总结

排序算法平均时间复杂度最好情况最坏情况空间复杂度稳定性适用场景
冒泡排序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(n log n)O(n log n)O(n²)O(log n)不稳定通用排序(平均性能最优)
希尔排序O(n log n)O(n log n)O(n²)O(1)不稳定中等规模数据
归并排序O(n log n)O(n log n)O(n log n)O(n)稳定大数据、外部排序、稳定性要求高
堆排序O(n log n)O(n log n)O(n log n)O(1)不稳定原地排序、避免最坏情况
计数排序O(n + k)O(n + k)O(n + k)O(n + k)稳定整数且范围小
桶排序O(n + k)O(n)O(n²)O(n + k)稳定数据均匀分布
基数排序O(d(n + k))O(d(n + k))O(d(n + k))O(n + k)稳定整数或字符串(位数固定)

关键总结

  1. 时间复杂度优先

    • 大规模数据:快速排序(平均O(n log n))。

    • 避免最坏情况:堆排序(始终O(n log n))。

    • 稳定且高效:归并排序(O(n log n) + 稳定)。

  2. 空间复杂度优先

    • 原地排序:堆排序、希尔排序(O(1))。

  3. 特殊场景

    • 小范围整数:计数排序(O(n + k))。

    • 均匀分布浮点数:桶排序(O(n))。

    • 多位数整数:基数排序(O(dn))。

  4. 稳定性要求:归并排序、计数排序、桶排序、基数排序。

  5. 小规模数据:插入排序(简单且稳定)。

实际建议

  • 通用场景:优先选择 快速排序(库函数常用)。

  • 内存敏感:选择 堆排序

  • 稳定性必需:选择 归并排序

  • 特定数据:根据范围/分布选择非比较排序(计数、桶、基数)。

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

相关文章:

  • 【操作系统】macOS软件提示“已损坏,打不开”的解决方案
  • 数字ic后端设计从入门到精通8(含fusion compiler, tcl教学)ULVTLL、LVT、ULVT详解及应用
  • 游戏技能编辑器界面优化设计
  • AEO:从搜索引擎到答案引擎,AI时代搜索优化的新战场
  • MSPM0G3507学习笔记(三)软硬I2C任意切换,兼容HAL:oled与mpu6050
  • RK 安卓10/11平台 HDMI-IN 调试
  • SSRF4 SSRF-gopher 协议扩展利用-向内网发起 GET/POST 请求
  • Java中间件使用方式与实战应用
  • 基于深度学习的智能文本摘要系统:技术与实践
  • 【音视频】SIP基础、搭建服务器和客户端
  • uniapp 配置devserver代理
  • P6 QT项目----汽车仪表盘(6.4)
  • C++ vector深度剖析与模拟实现:探索模板的泛型应用
  • 腾讯云国际站缩容:策略、考量与实践
  • 智慧园区建设资料合集(Wordppt原件)
  • Spring Boot 中的条件装配:@Conditional 系列注解详解
  • 答辩讲解387基于Spring Boot的心理健康管理系统
  • 【Python系列PyCharm实战】ModuleNotFoundError: No module named ‘sklearn’ 系列Bug解决方案大全
  • Windows Server系统只有命令行不显示桌面的解决方法
  • 【超详细】讯飞智能车PC电脑烧录指南(高级系统部署与恢复)
  • LDPC码校验矩阵和生成矩阵的生成
  • Java在IDEA中终端窗口输出正常,但打包成JAR后中文乱码问题
  • 《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- 实战基于CSI2 Rx 构建高性能摄像头输入系统
  • 51c嵌入式~电路~合集2
  • 【沉浸式解决问题】优化MySQL中多表union速度慢的问题
  • 数字化零售如何全面优化顾客体验
  • 深度融合数智化,百胜软件联合华为云加速零售行业转型升级
  • 删除大表数据注意事项
  • 字符操作函数续上
  • Vue 实现图片裁剪功能:基于 vue-cropper 和 Element Plus 的完整解决方案