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

Java常见排序算法实现

以下是Java中几种常见排序算法的实现,包括冒泡排序、选择排序、插入排序、快速排序和归并排序。

各排序算法特点说明:

  1. 冒泡排序

    • 原理:重复比较相邻元素,将大的元素逐步"冒泡"到数组末尾
    • 特点:稳定排序,适合小规模数据,可优化(加入交换标记提前退出)
    • 空间复杂度:O(1)(原地排序)
  2. 选择排序

    • 原理:每次从剩余元素中找到最小元素,放到已排序区间末尾
    • 特点:不稳定(可能改变相等元素的相对顺序),交换次数少
    • 空间复杂度:O(1)(原地排序)
  3. 插入排序

    • 原理:将元素逐个插入到前面已排序的区间中合适的位置
    • 特点:稳定排序,对近乎有序的数据效率很高(接近O(n))
    • 空间复杂度:O(1)(原地排序)
  4. 快速排序

    • 原理:通过分区操作将数组分为两部分,递归排序子数组
    • 特点:实际应用中最快的排序算法之一,不稳定,最坏情况性能差
    • 空间复杂度:O(log n)(递归栈空间)
  5. 归并排序

    • 原理:将数组分成两半分别排序,再合并两个有序子数组
    • 特点:稳定排序,性能稳定(始终O(n log n)),需要额外空间
    • 空间复杂度:O(n)(需要临时数组)
import java.util.Arrays;public class SortingAlgorithms {// 1. 冒泡排序(稳定,O(n²))public static void bubbleSort(int[] arr) {if (arr == null || arr.length <= 1) return;int n = arr.length;// 外层循环控制需要进行多少轮比较for (int i = 0; i < n - 1; i++) {boolean swapped = false;// 内层循环每轮将最大元素"冒泡"到末尾for (int j = 0; j < n - 1 - i; 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. 选择排序(不稳定,O(n²))public static void selectionSort(int[] arr) {if (arr == null || arr.length <= 1) return;int n = arr.length;// 外层循环控制未排序区间的起点for (int i = 0; i < n - 1; i++) {// 找到未排序区间中最小元素的索引int minIndex = i;for (int j = i + 1; j < n; j++) {if (arr[j] < arr[minIndex]) {minIndex = j;}}// 将最小元素与未排序区间的第一个元素交换int temp = arr[i];arr[i] = arr[minIndex];arr[minIndex] = temp;}}// 3. 插入排序(稳定,O(n²),适合近乎有序的数据)public static void insertionSort(int[] arr) {if (arr == null || arr.length <= 1) return;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--;}// 将key插入到正确位置arr[j + 1] = key;}}// 4. 快速排序(不稳定,平均O(n log n),最坏O(n²))public static void quickSort(int[] arr) {if (arr == null || arr.length <= 1) return;quickSort(arr, 0, arr.length - 1);}private static void quickSort(int[] arr, int left, int right) {if (left < right) {// 分区操作,返回基准元素的正确位置int pivotIndex = partition(arr, left, right);// 递归排序基准元素左右两侧的子数组quickSort(arr, left, pivotIndex - 1);quickSort(arr, pivotIndex + 1, right);}}private static int partition(int[] arr, int left, int right) {int pivot = arr[right]; // 以最右侧元素作为基准int i = left - 1; // i指向小于基准的元素的最后位置// 遍历数组,将小于基准的元素放到左侧for (int j = left; j < right; 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[right];arr[right] = temp;return i + 1; // 返回基准元素的索引}// 5. 归并排序(稳定,O(n log n),需要额外空间)public static void mergeSort(int[] arr) {if (arr == null || arr.length <= 1) return;mergeSort(arr, 0, arr.length - 1, new int[arr.length]);}private static void mergeSort(int[] arr, int left, int right, int[] temp) {if (left < right) {int mid = left + (right - left) / 2; // 避免溢出// 递归排序左右两半mergeSort(arr, left, mid, temp);mergeSort(arr, mid + 1, right, temp);// 合并两个有序子数组merge(arr, left, mid, right, temp);}}private static void merge(int[] arr, int left, int mid, int right, int[] temp) {int i = left; // 左子数组的起始索引int j = mid + 1; // 右子数组的起始索引int k = left; // 临时数组的起始索引// 合并两个子数组到临时数组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++];}// 将临时数组中的元素复制回原数组for (k = left; k <= right; k++) {arr[k] = temp[k];}}// 测试public static void main(String[] args) {int[] arr = {64, 34, 25, 12, 22, 11, 90};int[] copy;copy = Arrays.copyOf(arr, arr.length);bubbleSort(copy);System.out.println("冒泡排序: " + Arrays.toString(copy));copy = Arrays.copyOf(arr, arr.length);selectionSort(copy);System.out.println("选择排序: " + Arrays.toString(copy));copy = Arrays.copyOf(arr, arr.length);insertionSort(copy);System.out.println("插入排序: " + Arrays.toString(copy));copy = Arrays.copyOf(arr, arr.length);quickSort(copy);System.out.println("快速排序: " + Arrays.toString(copy));copy = Arrays.copyOf(arr, arr.length);mergeSort(copy);System.out.println("归并排序: " + Arrays.toString(copy));}
}

文章转载自:

http://oXrPa0vp.kscwt.cn
http://6q0w6FWG.kscwt.cn
http://X1RY89vW.kscwt.cn
http://XXYwr5Aj.kscwt.cn
http://FinkUIH7.kscwt.cn
http://N3lZyYHb.kscwt.cn
http://24fPHNJO.kscwt.cn
http://RKKjLbPr.kscwt.cn
http://jGULQDBA.kscwt.cn
http://OHGeMUQa.kscwt.cn
http://IUnQdR9N.kscwt.cn
http://HrXomxVO.kscwt.cn
http://3mOMPxj7.kscwt.cn
http://nRywJy4U.kscwt.cn
http://lm5pn7QU.kscwt.cn
http://uuy7QvDE.kscwt.cn
http://4Sb2gdIp.kscwt.cn
http://pDz9tBwz.kscwt.cn
http://N8yJ000R.kscwt.cn
http://BgLSJNz3.kscwt.cn
http://gffTWt0y.kscwt.cn
http://EZsOOp99.kscwt.cn
http://NVQmzcKS.kscwt.cn
http://xJXttGYl.kscwt.cn
http://GHWakmhf.kscwt.cn
http://EDyr0Fww.kscwt.cn
http://NdxhiaDB.kscwt.cn
http://K66BZN0L.kscwt.cn
http://fQJDISGA.kscwt.cn
http://xE6XPqvb.kscwt.cn
http://www.dtcms.com/a/378796.html

相关文章:

  • 生产环境禁用AI框架工具回调:安全风险与最佳实践
  • Git - Difftool
  • leetcode28( 汇总区间)
  • 直击3D内容创作痛点-火山引擎多媒体实验室首次主持SIGGRAPH Workshop,用前沿技术降低沉浸式内容生成门槛
  • 鸿蒙next kit 卡片引入在线|本地图片注意事项
  • 学习番外:Docker和K8S理解
  • Leetcode 刷题记录 21 —— 技巧
  • 卷积神经网络CNN-part5-NiN
  • 散斑深度相机原理
  • 中元的星问
  • 使用 NumPy 读取平面点集并分离列数据
  • uni-app + Vue3 开发展示 echarts 图表
  • uni-app 网络请求封装实战:打造高效、可维护的HTTP请求框架
  • AppTest邀请测试测试流程
  • C#地方门户网站 基于NET6.0、Admin.NET,uniapp,vue3,elementplus开源的地方门户网站项目
  • 苹果上架全流程详解,iOS 应用发布步骤、App Store 上架流程、uni-app 打包上传与审核要点完整指南
  • PyTorch之张量创建与运算
  • Python爬虫实战:研究GUI 可视化界面,构建电商数据采集和分析系统
  • 对浏览器事件机制的理解
  • JavaWeb05
  • 浅聊一下ThreadLocal
  • 部署大模型的极简笔记
  • linux面试题记录
  • 深度解码OpenAI的2025野心:Codex重生与GPT-5 APIKey获取调用示例
  • 文献阅读笔记:脉冲神经网络最新文献合集-IV
  • STM32学习路线开启篇:芯片简介与课程简介
  • 第七章 ELK Stack高级应用与集成
  • 认识跨平台UI框架Flutter和MAUI区别,如何选。
  • 9.11-QT-QT的基本使用
  • 线程安全相关的注解