快速排序和堆排序模板总结

堆排序以及快速排序模板

堆排序使用,215.数组中的第k个最大元素:https://leetcode.cn/problems/kth-largest-element-in-an-array

快速排序使用, 75.颜色分类: https://leetcode.cn/problems/sort-colors/

堆排序模板

public class MaxHeapSort {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 temp = arr[i];arr[i] = arr[largest];arr[largest] = temp;heapify(arr, n, largest);}}// 测试public static void main(String[] args) {int[] arr = {12, 11, 13, 5, 6, 7};System.out.println("原始数组:");printArray(arr);heapSort(arr);System.out.println("排序后的数组:");printArray(arr);}// 辅助函数,打印数组public static void printArray(int[] arr) {for (int i : arr) {System.out.print(i + " ");}System.out.println();}
}

首先,通过从数组的最后一个非叶子节点开始向前遍历,来进行循环,叶子节点的索引范围是从 heapSize / 2 到 0(包括边界值)。对于循环中,使用heapify堆化函数来进行当前子堆的排序。

注意,从最后一个非叶子节点开始遍历的意义就在于,此时非叶子节点对应最小的最大堆,从最小单元向上递归,保证子堆的堆顶元素一定最大

在循环中,对于每个节点,调用 heapify 方法,这个方法负责将当前节点及其子树调整为最大堆。因为最后一个非叶子节点的索引之后的节点都是叶子节点,它们自身已经是最大堆,所以只需要从最后一个非叶子节点开始往前遍历调用 heapify 方法即可。

heapify中元素,当发现堆顶largest发生了改变后,则说明需要发生交换,此时由于可能存在,与一边子树交换了,但另一边子树尚未交换,可能会破坏了它下面的子树的最大堆性质。所以需要递归地对交换后的子树进行堆化操作。

最后,如果需要排序,由于最大堆只能保证堆顶元素最大,因此需要循环取出元素,并每次取出后向下调整。

题解

因此最终得到对应题解

class Solution {public int findKthLargest(int[] nums, int k) {int heapSize = nums.length;buildMaxHeap(nums, heapSize); // 从最后一个非叶子节点递归,构建最大堆for (int i = nums.length - 1; i >= nums.length - k + 1; --i) {swap(nums, 0, i); //交换元素,因为此时最大堆性质下,只能保证堆顶是最大的,无法保证其他顺序,因此需要重复移除堆顶元素。--heapSize;maxHeapify(nums, 0, heapSize);}//上述循环内的三步骤其实就是删除堆元素的三部,1、将堆顶元素与堆底部交换。2、减少堆尺寸。3、执行最大堆,向下调整return nums[0];}public void buildMaxHeap(int[] a, int heapSize) {for (int i = heapSize / 2; i >= 0; --i) {maxHeapify(a, i, heapSize); //最后一个非叶子节点为}}public void maxHeapify(int[] a, int i, int heapSize) {// 父节点的下标 = (子节点下标 - 1) >> 1;// 左子节点下标 = 父节点下标 * 2 + 1;// 右子节点下标 = 父节点下标 * 2 + 2;int l = i * 2 + 1, r = i * 2 + 2, largest = i;if (l < heapSize && a[l] > a[largest]) {largest = l;}if (r < heapSize && a[r] > a[largest]) {largest = r;}if (largest != i) {swap(a, i, largest);maxHeapify(a, largest, heapSize);}}public void swap(int[] a, int i, int j) {int temp = a[i];a[i] = a[j];a[j] = temp;}
}

快速排序

由于颜色分类本身就适合快排,因此直接介绍:

快速排序的基本思想: 通过一趟排序将待排序的序列分割为左右两个子序列,左边的子序列中所有数据都比右边子序列中的数据小,然后对左右两个子序列继续进行排序,直到整个序列有序。

具体实现步骤是这样的,首先从序列中任意选择一个元素,把该元素作为枢轴,然后将小于等于枢轴的所有元素都移到枢轴的左侧,把大于枢轴的元素都移到枢轴的右侧。这样,以枢轴为界,划分出两个子序列,左侧子序列所有元素都小于右侧子序列。枢轴元素不属于任一子序列,并且枢轴元素当前所在位置就是该元素在整个排序完成后的最终位置。这样一个划分左右子序列的过程就叫做快速排序的一趟排序,或称为一次划分。递归此划分过程,直到整个序列有序。

一般来说,初始值一般选择为数组得中间元素,但是也可以选择第一个元素,仅仅实现简单。

题解

class Solution {public void sortColors(int[] nums) {int l = 0, r = nums.length - 1;quickSelect(nums, 0, nums.length - 1);}public void quickSelect(int[] nums, int l, int r) {if (l == r) return;// left = l, right = r; 同时不是do-while循环的话,很可能出现两个数值相等,且与x相等的情况,导致死循环// left = l - 1主要是为了do-while第一次的时候,能取到边界值。int left = l - 1, right = r + 1, x = nums[(l + r)/2];while (left < right) {do left++; while (nums[left] < x);do right--; while (nums[right] > x);if (left < right) {int temp = nums[left];nums[left] = nums[right];nums[right] = temp;}}quickSelect(nums, l , right);quickSelect(nums, right + 1, r);}
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【AI学习指南】九、PaddlePaddle自然语言处理-PaddleNLP SKEP情感分析定制化训练(万字长文附代码)

目录 加载预训练模型到指定位置 加载分词器 准备数据集 train.tsv 文件内容示例: dev.tsv 文件

第一次Python小练习题目

1.打印某学校的校训&#xff0c;具体内容如下所示&#xff1a; ****************************** 勤奋 严谨 求实 创新 ****************************** 注意: 第一行和最后一行各有 30 个*号。 答案&#xff1a; school_strs "勤奋 严谨 求实 创新&q…

8.找到字符串中所有字母异位词

给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串&#xff08;包括相同的字符串&#xff09;。 示例 1: 输入: s "cbaebabacd", p "…

申请选择商家转账到零钱流程怎样的

商家转账到零钱是什么&#xff1f; 【商家转账到零钱】可以说是【企业付款到零钱】的升级版&#xff0c;商家转账到零钱可以为商户提供同时向多个用户微信零钱转账的能力&#xff0c;支持分销返佣、佣金报酬、企业报销、企业补贴、服务款项、采购货款等自动向用户转账的场景。…

如何关闭微软的Edge浏览器右击提示的:“使用copilot重写“的提示?

最近在使用微软的edge浏览器写文档的时候&#xff0c;总是不小心右击鼠标&#xff0c;提示 有时候挺烦人的&#xff0c;那怎么关闭呢&#xff1f; 打开edge浏览器的设置 在设置中搜索AI&#xff0c;并关闭AI书写的选项就好了 这样就可以获得一个干净的界面了&#xff0c;不…

微信小程序重新加载当前页面、刷新当前页面

重新加载页面 使用wx.reLanuch&#xff08;&#xff09;&#xff0c;url: 路径当前页面跳转, 页面所有数据重新初始化&#xff0c;已配置的数据不会保存 wx.reLaunch({url: /pages/orders/createOrder/createOrder, // 当前页面的路径}) reLanuch()的方法&#xff0c;会有一个…

向指定接口上传文件

post请求&#xff0c;参数为接口地址&#xff0c;文件的绝对路径&#xff0c;例如&#xff1a;D:/files/a.txt&#xff0c; 返回结构如下&#xff1a; {"code": 200,"message": "成功","data": "1231312313","ok&quo…

什么是APP封装?APP封装有什么途径?APP封装如何实现?

APP封装是形成APP成本最低的一种方式。你只需要拥有一个手机端的网址就可以通过一些技术处理封装成一个跨iOS和Android的APP&#xff0c;这个过程往往只需要几分钟。既节省时间又能节省开发的成本资金&#xff0c;所以接下来就介绍一下大家都比较关心的怎么给手机网站封装打包成…

基于pytest的证券清算系统功能测试工具开发

需求 1.造测试数据&#xff1a;根据测试需要&#xff0c;自动化构造各业务场景的中登清算数据与清算所需起来数据 2.测试清算系统功能&#xff1a; 自动化测试方案 工具设计 工具框架图 工具流程图 实现技术 python, pytest, allure, 多进程&#xff0c;mysql, 前端 效果 测…

探索 PostgreSQL 的高级数据类型 - 第 二 部分

范围类型 范围类型提供了一种简洁的方式来表示单个数据库字段中的值范围。它们在从时间数据到数字间隔的各种领域中都有应用。在本篇博客文章中&#xff0c;我们将通过 DML/SQL 语句和 Navicat for PostgreSQL 16 来深入了解它们的使用&#xff08;以及好处&#xff01;&#…

STM32存储左右互搏 SPI总线读写SD/MicroSD/TF卡

STM32存储左右互搏 SPI总线读写SD/MicroSD/TF卡 SD/MicroSD/TF卡是基于FLASH的一种常见非易失存储单元&#xff0c;由接口协议电路和FLASH构成。市面上由不同尺寸和不同容量的卡&#xff0c;手机领域用的TF卡实际就是MicroSD卡&#xff0c;尺寸比SD卡小&#xff0c;而电路和协…

C/C++ 人们自行构建高性能反射框架,应该怎么设计比较好。

在 C/C 之中默认提供的 “RTTI” 运行时类型信息反射机制过于脆弱&#xff0c;基本就等于没什么卵用&#xff0c;但在 C/C 11 之前模板元编程不是那么强大的时候&#xff0c;还是有那么一点点作用。 我们通常利用RTTI反射T的类型或其泛型类型&#xff08;即T的T&#xff09;&am…

数学建模-多目标规划算法(美赛建模)

单目标优化的情况下&#xff0c;只有一个目标&#xff0c;任何两解都可以依据单一目标比较其好坏&#xff0c;可以得出没有争议的最优解。 多目标化与传统的单目标优化相对。多目标优化的概念是在某个情景中在需要达到多个目标时&#xff0c;由于容易存在目标间的内在冲突&…

7 BUILD.gn文件怎么写,Gn + Ninja编译一个Hello world程序的例子Demo

BUILD.gn文件怎么写&#xff0c;Gn Ninja编译一个Hello world程序的例子Demo 作者将狼才鲸创建日期2024-03-11 Ninja安装流程见&#xff1a;一个能直接运行的Ninja例子&#xff0c;build.ninja文件怎么写&#xff1f;Gn安装流程见&#xff1a;Ubuntu18.04下安装Gn软件 这是一…

webpack如何去自定义一个Loader?(大白话,so easy!)

文章目录 关注小白菜&#xff0c;前端变更菜&#xff0c;不定期更新csdn&#xff0c;内容不定看心情随便写点&#xff0c;因为近期在面试&#xff0c;所以整理一下写点笔记&#xff0c;希望可以帮到初中级的同学们&#xff0c;加油&#xff0c;奥里给&#xff01;&#xff01;&…

生成验证码图片

引入依赖包 <!-- 图形验证码 --> <dependency><groupId>com.github.penggle</groupId><artifactId>kaptcha</artifactId><version>2.3.2</version> </dependency> 配置DefaultKaptcha类 类方法配置了验证码的生成格式…

目标检测数据集:手机顶盖焊缺陷检测数据集

✨✨✨✨✨✨目标检测数据集✨✨✨✨✨✨ 本专栏提供各种场景的数据集,主要聚焦:工业缺陷检测数据集、小目标数据集、遥感数据集、红外小目标数据集,该专栏的数据集会在多个专栏进行验证,在多个数据集进行验证mAP涨点明显,尤其是小目标、遮挡物精度提升明显的数据集会在该…

std::thread 的构造-源码解析

std::thread 的构造-源码解析 我们这单章是为了专门解释一下 std::thread 是如何构造的&#xff0c;是如何创建线程传递参数的&#xff0c;让你彻底了解这个类。 我们以 MSVC 实现的 std::thread 代码进行讲解。 std::thread 的数据成员 了解一个庞大的类&#xff0c;最简单…

Anaconda环境全局环境手动配置

Anaconda环境全局环境手动配置 如图&#xff0c;在本机就有Anaconda的情况下&#xff0c;普通cmd无法直接使用conda命令&#xff0c;每次都要从Anaconda Prompt窗口操作&#xff0c;挺不方便的&#xff0c;遂决定进行全局环境配置&#xff0c;记录一下流程。 找到环境配置页面…

R语言绘制散点密度图ggdentity

使用R语言绘制二维密度图 下图是一张常见的二维核密度散点图&#xff0c;能够清晰直观的反映出数据之间的分布趋势&#xff0c;颜色越红的位置数据越集中分布。今天分享的笔记是在R语言中绘制该图的两种常见方法&#xff0c;提供过程代码。 论文中常见的这种展示两组数据之间分…