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

算法之常见八大排序

算法说明:

  1. 冒泡排序:重复比较相邻元素,将较大的元素向后移动
  2. 选择排序:每次选择最小元素放到已排序序列末尾
  3. 插入排序:将元素插入到已排序序列的正确位置
  4. 希尔排序:改进的插入排序,通过分组减少移动次数
  5. 归并排序:分治法,递归排序子数组后合并
  6. 快速排序:选择枢轴元素,将数组分为两部分递归排序
  7. 堆排序:利用堆数据结构进行选择排序
  8. 桶排序:将元素分配到多个桶中,分别排序后合并

代码案例:

import java.util.Arrays;public class SortingAlgorithms {public static void main(String[] args) {int[] arr = {64, 34, 25, 12, 22, 11, 90};System.out.println("原始数组: " + Arrays.toString(arr));// 测试不同排序算法(每次测试前复制数组)testSort("冒泡排序", SortingAlgorithms::bubbleSort, arr.clone());testSort("选择排序", SortingAlgorithms::selectionSort, arr.clone());testSort("插入排序", SortingAlgorithms::insertionSort, arr.clone());testSort("希尔排序", SortingAlgorithms::shellSort, arr.clone());testSort("归并排序", SortingAlgorithms::mergeSort, arr.clone());testSort("快速排序", SortingAlgorithms::quickSort, arr.clone());testSort("堆排序  ", SortingAlgorithms::heapSort, arr.clone());testSort("桶排序  ", SortingAlgorithms::bucketSort, arr.clone());}private static void testSort(String name, RunnableSorter sorter, int[] arr) {long startTime = System.nanoTime();sorter.run(arr);long endTime = System.nanoTime();System.out.printf("%s: %s (耗时: %.3f ms)%n", name, Arrays.toString(arr),(endTime - startTime) / 1_000_000.0);}@FunctionalInterfaceinterface RunnableSorter {void run(int[] arr);}// 八大排序实现方法// 1. 冒泡排序:重复比较相邻元素,将较大的元素向后移动public static void bubbleSort(int[] arr) {int n = arr.length;for (int i = 0; i < n - 1; i++) {boolean swapped = false;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;swapped = true;}}// 如果没有发生交换,说明已经有序if (!swapped) break;}}// 2. 选择排序:每次选择最小元素放到已排序序列末尾public static 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[minIdx];arr[minIdx] = arr[i];arr[i] = temp;}}// 3. 插入排序:将元素插入到已排序序列的正确位置public static void insertionSort(int[] arr) {int n = arr.length;for (int i = 1; i < n; i++) {int key = arr[i];int j = i - 1;// 将大于key的元素后移while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];j--;}arr[j + 1] = key;}}// 4. 希尔排序:改进的插入排序,通过分组减少移动次数public static 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;for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {arr[j] = arr[j - gap];}arr[j] = temp;}}}// 5. 归并排序:分治法,递归排序子数组后合并public static void mergeSort(int[] arr) {if (arr.length > 1) {int mid = arr.length / 2;int[] left = Arrays.copyOfRange(arr, 0, mid);int[] right = Arrays.copyOfRange(arr, mid, arr.length);mergeSort(left);mergeSort(right);// 合并两个有序数组int i = 0, j = 0, k = 0;while (i < left.length && j < right.length) {if (left[i] < right[j]) {arr[k++] = left[i++];} else {arr[k++] = right[j++];}}// 处理剩余元素while (i < left.length) arr[k++] = left[i++];while (j < right.length) arr[k++] = right[j++];}}// 6. 快速排序:选择枢轴元素,将数组分为两部分递归排序public static void quickSort(int[] arr) {quickSort(arr, 0, arr.length - 1);}private static 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 static 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;}// 7. 堆排序:利用堆数据结构进行选择排序public static 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 static 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) {int swap = arr[i];arr[i] = arr[largest];arr[largest] = swap;// 递归堆化受影响的子树heapify(arr, n, largest);}}// 8. 桶排序:将元素分配到多个桶中,分别排序后合并// 桶排序 (假设元素范围在0-100)public static void bucketSort(int[] arr) {if (arr.length == 0) return;// 确定最大值int maxVal = Arrays.stream(arr).max().getAsInt();// 创建桶int bucketCount = maxVal / 10 + 1;int[][] buckets = new int[bucketCount][0];// 分配元素到桶中for (int num : arr) {int bucketIndex = num / 10;buckets[bucketIndex] = Arrays.copyOf(buckets[bucketIndex], buckets[bucketIndex].length + 1);buckets[bucketIndex][buckets[bucketIndex].length - 1] = num;}// 对每个桶排序(这里使用插入排序)int index = 0;for (int[] bucket : buckets) {if (bucket.length > 0) {insertionSort(bucket); // 可以使用任意排序算法for (int num : bucket) {arr[index++] = num;}}}}
}

注意:桶排序的性能取决于数据分布和桶的数量,代码中假设数据范围在0-100,实际使用时需要根据数据范围调整桶的数量。

时间复杂度对比:

算法平均时间复杂度最坏时间复杂度空间复杂度稳定性
冒泡O(n²)O(n²)O(1)稳定
选择O(n²)O(n²)O(1)不稳定
插入O(n²)O(n²)O(1)稳定
希尔O(n log n)O(n²)O(1)不稳定
归并O(n log n)O(n log n)O(n)稳定
快速O(n log n)O(n²)O(log n)不稳定
O(n log n)O(n log n)O(1)不稳定
O(n+k)O(n²)O(n+k)稳定

文章转载自:

http://AOWSomly.cndxL.cn
http://NoylKUy0.cndxL.cn
http://zV5ASxZv.cndxL.cn
http://soJZT0gq.cndxL.cn
http://vXzaL9NZ.cndxL.cn
http://KuMWKLB9.cndxL.cn
http://gWCEH27s.cndxL.cn
http://HDB8eamk.cndxL.cn
http://ANTx8UBR.cndxL.cn
http://tLpiMD1G.cndxL.cn
http://5LQEXrbw.cndxL.cn
http://IdMNwQx6.cndxL.cn
http://K6fzenuB.cndxL.cn
http://2JIyyFNp.cndxL.cn
http://uazhquFf.cndxL.cn
http://lencmL6F.cndxL.cn
http://sPrcBE1I.cndxL.cn
http://OMiJRroj.cndxL.cn
http://xoKdmmeg.cndxL.cn
http://4X6sBNiA.cndxL.cn
http://C707Jbam.cndxL.cn
http://QX6661Gj.cndxL.cn
http://pN6IcgQc.cndxL.cn
http://oy92E3OL.cndxL.cn
http://w5HFsUru.cndxL.cn
http://d70yOWgw.cndxL.cn
http://TgNvolNT.cndxL.cn
http://XgflFLPZ.cndxL.cn
http://j9ST4Hq1.cndxL.cn
http://ZiyIwS4I.cndxL.cn
http://www.dtcms.com/a/373652.html

相关文章:

  • 某公共资源中心-sm2逆向
  • 数电实验二任务验证指南(开关操作与指示灯观察)
  • Redis Stream:轻量级消息队列深度解析
  • RAG-5-案例1
  • 点亮智慧城市:智能照明开关驱动器如何重塑路灯控制新纪元
  • 开发中使用——鸿蒙播放本地mp3文件
  • DLL修复是什么意思?为什么总会缺失?(详细教程)
  • 高强度应用下天硕工业级SSD固态硬盘真的更耐用吗?
  • c++基础学习(学习蓝桥杯 ros2有C基础可看)
  • SpringBoot学习日记 Day10:企业级博客系统开发实战(一)
  • 嵌入式学习---(硬件)
  • 写算法第二题(英语介词)dom对象
  • cn2an:中文数字与阿拉伯数字的智能转换工具
  • Hive和Flink数据倾斜问题
  • 嵌入式ARM架构学习2——汇编
  • 渗透测试全景解析:从基础概念到实战演练
  • 鸿蒙Next应用UI稳定性故障调试:从崩溃到流畅的实战指南
  • 企智汇施工工程项目管理系统:全生命周期信息化管理解决方案!施工企业管理系统!施工企业项目管理软件!工程项目管理系统!工程项目管理软件!
  • 遥感数据同化方法:集合卡尔曼滤波和变分同化算法
  • mac安装Java开发环境
  • Java网络初识(2):IP地址和端口号,协议,五元组
  • 什么是算法:高效解决问题的逻辑框架
  • EFCore与EF6:ORM技术深度解析
  • 【开题答辩全过程】以 线上“三味书屋”学习平台设计与实现为例,包含答辩的问题和答案
  • iframe引入界面有el-date-picker日期框,点击出现闪退问题处理
  • BP-Adaboost模型
  • 使用redis的发布/订阅(Pub/Sub), 实现消息队列
  • 鸿蒙:更改状态栏、导航栏颜色
  • [数据结构——lesson4.双向链表]
  • 集成学习:从理论到实践的全面解析