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

【常见排序算法】java 代码实现

排序算法时间复杂度空间复杂度稳定性排序策略递归性适应性
直接插入排序O(n²)O(1)稳定插入类非递归自适应
二分插入排序O(n²)O(1)稳定插入类非递归自适应
希尔排序O(n^1.3)~O(n²)O(1)不稳定插入类非递归部分自适应
冒泡排序O(n²)O(1)稳定交换类非递归自适应
快速排序O(n log n)O(log n)不稳定交换类递归非自适应
归并排序O(n log n)O(n)稳定归并类递归非自适应

直插排序

public static void straight_insert_sort(int[] r, int n) {// 直接插入排序:将未排序元素逐个插入到已排序序列的适当位置// 假设数组索引从1开始,r[0]作为哨兵,不参与排序int i, j;// 从第2个元素开始,逐个插入到前面已排序部分for (i = 2; i <= n; i++) {r[0] = r[i];  // 将当前待插入元素暂存到哨兵位置j = i - 1;    // 已排序部分的最后一个元素// 从后向前查找插入位置,同时移动元素while (r[0] < r[j]) {r[j + 1] = r[j];  // 元素后移一位j--;              // 继续向前比较}// 找到插入位置,将暂存的元素插入r[j + 1] = r[0];}
}

二分插入排序

public static void binary_insert_sort(int[] r) {// 二分插入排序:结合二分查找优化的插入排序// 假设数组索引从1开始,r[0]作为哨兵,不参与排序int i, j, low, high, mid;// 从第2个元素开始,逐个插入到前面已排序部分for (i = 2; i < r.length; i++) {r[0] = r[i];  // 将当前待插入元素暂存到哨兵位置low = 1;      // 已排序部分的起始位置high = i - 1; // 已排序部分的结束位置// 二分查找插入位置while (low <= high) {mid = (low + high) / 2;  // 计算中间位置if (r[0] < r[mid]) {     // 插入位置在左半部分high = mid - 1;} else {                 // 插入位置在右半部分low = mid + 1;}}// 找到插入位置后,将元素后移for (j = i - 1; j >= high + 1; j--) {r[j + 1] = r[j];  // 元素后移一位}// 在找到的位置插入元素r[high + 1] = r[0];}
}

希尔排序

public static void shell_sort(int[] r) {// 希尔排序:基于插入排序的改进算法// 通过设置不同的间隔(d),将数组分成多个子序列进行排序// 随着间隔逐渐减小,数组逐渐接近有序,最终间隔为1时完成排序int d, i, j;// 初始间隔为数组长度的一半,然后每次减半for (d = r.length / 2; d >= 1; d = d / 2) {// 对每个子序列进行插入排序for (i = d + 1; i < r.length; i++) {r[0] = r[i];  // 暂存当前元素j = i - d;    // 子序列的前一个元素// 在子序列中向前查找插入位置while (j > 0 && r[0] < r[j]) {r[j + d] = r[j];  // 元素后移d个位置j = j - d;        // 继续向前查找}// 插入元素r[j + d] = r[0];}}
}

冒泡排序

public static void bubbleSort(int[] r, int n) {int exchange, bound;// exchange: 记录最后一次交换的位置// bound: 每轮比较的右边界exchange = n;  // 初始时,整个数组都需要排序while (exchange != 0) {  // 只要还有交换发生,就继续排序bound = exchange;  // 上一轮最后一次交换的位置,作为本轮的右边界exchange = 0;  // 重置交换位置,准备记录本轮的最后一次交换for (int j = 1; j < bound; j++) {  // 只需要比较到上一轮最后交换的位置if (r[j] > r[j + 1]) {  // 如果前一个元素比后一个大,就交换r[0] = r[j];  // 交换元素r[j] = r[j + 1];r[j + 1] = r[0];exchange = j;  // 记录最后一次交换的位置}}// 循环结束后,bound之后的元素已经有序,下一轮只需比较到bound位置}
}

快速排序

public static void quickSort(int[] r, int first, int end) {// 快速排序的递归实现// 参数://   r: 待排序数组//   first: 当前子数组的起始索引//   end: 当前子数组的结束索引if (first < end) {  // 递归终止条件:子数组长度大于1// 分区操作:将数组分为两部分// 左边部分 <= 基准,右边部分 >= 基准// pivot 是基准元素最终所在的位置int pivot = partition(r, first, end);// 递归排序左半部分quickSort(r, first, pivot - 1);// 递归排序右半部分quickSort(r, pivot + 1, end);}// 当 first >= end 时,子数组长度为0或1,已经有序,直接返回
}public static int partition(int[] r, int first, int end) {// 以第一个元素为基准,将数组分为两部分// 左边部分 <= 基准,右边部分 >= 基准// 返回基准元素最终所在的位置int i = first, j = end, temp;  // i: 左指针,j: 右指针while (i < j) {  // 当左右指针未相遇时,继续分区// 从右向左找第一个小于基准的元素while (i < j && r[i] <= r[j]) j--;if (i < j) {  // 如果找到,交换左右指针所指元素temp = r[i];r[i] = r[j];r[j] = temp;i++;  // 左指针右移}// 从左向右找第一个大于基准的元素while (i < j && r[i] <= r[j]) i++;if (i < j) {  // 如果找到,交换左右指针所指元素temp = r[i];r[i] = r[j];r[j] = temp;j--;  // 右指针左移}}// 当i=j时,分区完成,返回基准元素的位置return i;
}

归并排序

public static void mergesort(int[] r, int s, int t) {// 参数://   r: 待排序数组//   s: 当前子数组的起始索引//   t: 当前子数组的结束索引int i, m;// 递归终止条件:当子数组只有一个元素时,直接返回if (s == t) return;// 计算中间位置,将数组分成两部分m = (s + t) / 2;// 递归排序左半部分mergesort(r, s, m);// 递归排序右半部分mergesort(r, m + 1, t);// 合并已排序的两部分merge(r, s, m, t);
}public static void merge(int[] r, int s, int m, int t) {// 参数://   r: 待合并数组//   s: 左子数组的起始索引//   m: 左子数组的结束索引(也是中间位置)//   t: 右子数组的结束索引// 创建辅助数组,用于临时存储合并结果int[] r1 = new int[t + 1];// i: 左子数组的当前索引// j: 右子数组的当前索引// k: 辅助数组的当前索引int i = s, j = m + 1, k = s;// 同时遍历左右子数组,将较小的元素放入辅助数组while (i <= m && j <= t) {if (r[i] <= r[j]) {r1[k++] = r[i++];  // 左子数组元素较小,放入辅助数组} else {r1[k++] = r[j++];  // 右子数组元素较小,放入辅助数组}}// 处理左子数组剩余元素while (i <= m) {r1[k++] = r[i++];}// 处理右子数组剩余元素while (j <= t) {r1[k++] = r[j++];}// 将辅助数组中的元素复制回原数组for (i = s; i <= t; i++) {r[i] = r1[i];}
}

http://www.xdnf.cn/news/13931.html

相关文章:

  • Power Query动态追加查询(对文件夹下文件汇总)
  • WebSocket 前端断连原因与检测方法
  • Bean对象不同的方式注入,是不同的annotation接口描述
  • Java单元测试
  • 【走进Golang】测试SDK环境搭建成功,配置path环境变量
  • 深入剖析AI大模型:Prompt 开发工具与Python API 调用与技术融合
  • idea中导入maven项目的方法
  • AWS S3:云存储的“超级基石”
  • Coze扣子 - AI生成数字人口播视频
  • freeswitch使用hiredis的limit功能
  • <8>-MySQL复合查询
  • java发送excel附件的邮件
  • 计算机视觉与深度学习 | 2024年至2025年图像匹配算法总结(原理,公式,代码,开源链接)
  • 【白雪讲堂】当前GEO是否能追溯数据源?
  • 6.13 note | 二分查找
  • 基于大模型预测单纯性孔源性视网膜脱离的技术方案
  • 轻量级密码算法PRESENT的C语言实现(无第三方库)
  • 基于RK3588,飞凌教育品牌推出嵌入式人工智能实验箱EDU-AIoT ELF 2
  • C语言多进程TCP服务器与客户端
  • 【论文阅读笔记】CVPR2025 | 2D高斯溅射的几何-光照解耦:Ref-GS实现开放世界级真实渲染
  • Java 实现 Excel 转化为 PDF
  • OceanBase (DBA)一面面经
  • DMC-E 系列总线控制卡----雷赛板卡介绍(六)
  • 使用 ollama 在 mac 本地部署一个 qwen3:8b 模型
  • 26考研 | 王道 | 计算机组成原理 | 六、总线
  • 传统企业数字化转型:以定制开发开源 AI 智能名片 S2B2C 商城小程序源码为核心的销售环节突破
  • Python爬虫实战:研究gearman相关技术
  • 计算机视觉与深度学习 | 低照度图像增强算法综述(开源链接,原理,公式,代码)
  • Spring Boot常用依赖大全:从入门到精通
  • Ecc option开启后报错解决(植入实际程序后)