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

排序算法:堆排序、快速排序、归并排序

堆排序

性能:时间复杂度 O(nlogn),空间复杂度 O(1),不稳定

思路:把数组看做一个完全二叉树的结构,建立大顶堆(或小顶堆),排序就是把最顶层的根节点与末尾元素交换,然后继续从最顶层的根节点开始维护堆,循环往复就变成一个有序集合了。

  • 大顶堆:每个节点的值都大于或等于其子节点的值。堆顶(根节点)是整个堆的最大值。

  • 小顶堆:每个节点的值都小于或等于其子节点的值。堆顶(根节点)是整个堆的最小值。

最开始建堆时,从最后一个非叶子节点开始(因为在对一个节点进行操作时,其实是需要其子节点已经是大顶堆(或小顶堆),其实从我们要做的事情也可以理解,因为我们是要把最大或最小移动到最顶层,所以也应该是自底向上),自底向上调整堆。

代码如下:

public class HeapSort {/*** 堆排序* @param arr 待排序数组*/public static void sort(int[] arr) {int n = arr.length;// 从最后一个非叶子结点开始调整堆for (int i = n / 2 - 1; i >= 0; i--) {adjustHeapIterative(arr, i, n);}// 排序,把最大值依次放入末尾,继续调整接下来的堆for (int i = n - 1; i > 0; i--) {swap(arr, 0, i);adjustHeapIterative(arr, 0, i);}}/*** 迭代方式的堆调整(下沉)操作 O(1)* @param arr 待调整的数组* @param root 要下沉的根节点索引* @param len 堆的有效大小*/private static void adjustHeapIterative(int[] arr, int root, int len) {int temp = arr[root]; // 保存根节点的值int current = root;   // 当前要调整的节点// 从根节点开始向下调整while (current * 2 + 1 < len) { // 如果有左孩子int left = current * 2 + 1;int right = current * 2 + 2;int largest = left; // 假设左孩子是较大的// 如果右孩子存在且比左孩子大if (right < len && arr[right] > arr[left]) {largest = right;}// 如果较大的孩子比当前节点大,需要交换if (arr[largest] > temp) {arr[current] = arr[largest]; // 将较大的孩子上移current = largest;           // 继续向下调整} else {break; // 当前节点已经比两个孩子都大,调整结束}}arr[current] = temp; // 将最初根节点的值放到最终位置}/*** 调整堆(递归)使用递归还是会消耗栈空间* @param arr 数组* @param root 调整的根节点* @param len 边界*/private static void adjustHeap(int[] arr, int root, int len) {int tempRoot = root;int left = tempRoot * 2 + 1;int right = tempRoot * 2 + 2;// 找到最大的子节点交换if (left < len && arr[left] > arr[tempRoot]) {tempRoot = left;}if (right < len && arr[right] > arr[tempRoot]) {tempRoot = right;}// 调整有变动的子树if (tempRoot != root) {swap(arr, tempRoot, root);adjustHeap(arr, tempRoot, len);}}private static void swap(int[] arr, int a, int b) {int temp = arr[a];arr[a] = arr[b];arr[b] = temp;}}
快速排序

性能:时间复杂度 O(nlogn)~O(n^2),空间复杂度  O(log n) ~ O(n),不稳定

思路:对于一个待排序数组,选取一个基准值,把比它小的元素移动到左边,其他移动到右边,也就是左边的元素都比右边的元素小,然后再递归处理左边和右边的元素,最终有序。

基准值的选取:通常是采用随机的方式,因为理想状态是把数组对半分,这样效率是最好的,避免这个基准值过于边缘,这样可能出现最差时间复杂度 O(n^2),通过随机来进行平衡。

代码如下:

import java.util.Random;public class QuickSort {private final static Random random = new Random();public static void sort(int[] arr) {quickSort(arr, 0, arr.length - 1);}/*** 快速排序* @param arr 待排序数组* @param l 左端点* @param r 右端点*/private static void quickSort(int[] arr, int l, int r) {if (l >= r) return;// 随机选取基准值,让每次选取基准值更平均,避免出现极端情况int point = (random.nextInt() % (r - l + 1)) + l;swap(arr, l, point);// 保证左边的数都小于等于基准,右边都大于基准int i = l + 1, j = r;// 左边比基准值大的 和 右边比基准值小的 交换while (i < j) {// 两边都拿到第一个满足条件的while (i < j && arr[i] <= arr[l]) {i++;}while (i < j && arr[j] > arr[l]) {j--;}swap(arr, i, j);}if (arr[i] > arr[l]) {i--;}swap(arr, i, l);// 继续处理两边的quickSort(arr, l, i);quickSort(arr, i + 1, r);}private static void swap(int[] arr, int a, int b) {int temp = arr[a];arr[a] = arr[b];arr[b] = temp;}}
归并排序

性能:时间复杂度 O(nlogn),空间复杂度  O(n),稳定

思路:利用分治思想,把数组对半分,先把子数组排好序,最后合并结果。

代码如下:

public class MergeSort {public static void sort(int[] arr) {mergeSort(arr, 0, arr.length - 1);}private static void mergeSort(int[] arr, int l, int r) {if (l >= r) return;// 取中点,对两边进行排序int mid = l + (r - l) / 2;mergeSort(arr, l, mid);mergeSort(arr, mid + 1, r);// 合并两个有序结果merge(arr, l, mid, r);}private static void merge(int[] arr, int l, int m, int r) {int[] temp = new int[r - l + 1];int i = l, j = m + 1;int k = 0;while (i <= m && j <= r) {if (arr[i] <= arr[j]) {temp[k++] = arr[i++];} else {temp[k++] = arr[j++];}}while (i <= m) temp[k++] = arr[i++];while (j <= r) temp[k++] = arr[j++];// 用合并好的覆盖掉之前的System.arraycopy(temp, 0, arr, l, temp.length);}
}
总结(deepseek)

http://www.dtcms.com/a/581411.html

相关文章:

  • qData 数据中台开源版 v1.0.7 发布:新增 SQL Server 支持,快速部署支持达梦与 MySQL 主库切换!
  • Qt 自定义加载动画控件:带文字提示的等待 spinner 实现
  • 织梦做淘宝客网站视频教程移动互联网开发找工作
  • Vue3 任务管理器(Pinia 练习)
  • 没有域名可以做网站吗个人网页设计绘画作品
  • 百胜软件做客华为云生态直播间:全渠道中台如何赋能零售数字化与全球布局?
  • 航电系统架构演进与要点概述
  • 华为云ELB
  • 医疗智能体(eiHealth) 3.4.0 使用指南(for 华为云Stack 8.5.0) 0. 华为除了这个 还有医疗 和生信方面的 产品
  • 写作教学网站wordpress 管理员账号在哪里查询
  • 完善服务终端:一洽对话结束与异常场景提示语设置
  • 从阿里云大模型服务平台百炼看AI应用集成与实践
  • 【图像处理】图像的基础几何变换
  • uniapp + uni-ui + vue3转cli
  • 户外保险网站wordpress icon 插件
  • config.json 完全指南:项目配置的核心实践
  • 【App开发】ADB 详细使用教程- Android 开发新人指南
  • 如何提高网站访客数重庆关键词排名首页
  • 天猫、飞猪打通了迪士尼会员权益 IP 商业化迈入“全域变现”时代
  • 第八章 惊喜22 批判性思维
  • wordpress主题模板视频网站模板实搜网站建设
  • 第1章 SLAM技术导论
  • 测试之bug篇
  • 万全县城乡建设网站企业网站建设的目的是什么
  • 网站建设资源平台地方门户网站的分类
  • VS + Qt 开发多语言,中英文
  • 游戏开发入门,简单小游戏原理-关于2D渲染的一些小想法
  • Bootstrap4 徽章(Badges)
  • CSE(ChannelSigExplorer)生物电单信道可视化分析平台
  • IntelliJ IDEA 插件开发指南,编写你的第一个IDEA插件