Java手写快速选择算法应用拓展案例

Java手写快速选择算法应用拓展案例

1. 引言

快速选择算法是一种高效的选择算法,可以用于在数组中找到第K小/大的元素。除了基本的应用场景外,快速选择算法还可以应用于其他问题,如查找中位数、查找最大/最小值等。本文将介绍两个拓展应用案例,并提供完整的代码和步骤描述。

2. 拓展应用案例1:查找中位数

中位数是一个有序数组中的中间值。通过快速选择算法,我们可以快速找到一个数组的中位数。

2.1 步骤描述

  1. 定义一个方法 findMedian,接受一个整型数组 arr 作为参数。
  2. 调用 quickSelect 方法,传入数组 arr、左边界 0、右边界 arr.length - 1 和中位数的位置 (arr.length + 1) / 2
  3. quickSelect 方法中,选择基准元素 pivot,并调用 partition 方法进行分区。
  4. 根据 partition 方法的返回值 index,判断中位数的位置:
    • 如果 index 等于 (arr.length + 1) / 2 - 1,则返回 arr[index]
    • 如果 index 大于 (arr.length + 1) / 2 - 1,则递归调用 quickSelect 方法,在左半部分数组中查找中位数。
    • 如果 index 小于 (arr.length + 1) / 2 - 1,则递归调用 quickSelect 方法,在右半部分数组中查找中位数。
  5. main 方法中,调用 findMedian 方法,并打印中位数的值。

2.2 完整代码

public class QuickSelectMedian {public static void main(String[] args) {int[] arr = {5, 3, 8, 2, 9, 1};int median = findMedian(arr);System.out.println("中位数是:" + median);}private static int findMedian(int[] arr) {return quickSelect(arr, 0, arr.length - 1, (arr.length + 1) / 2);}private static int quickSelect(int[] arr, int left, int right, int k) {int pivot = selectPivot(arr, left, right);int index = partition(arr, left, right, pivot);if (index == k - 1) {return arr[index];} else if (index > k - 1) {return quickSelect(arr, left, index - 1, k);} else {return quickSelect(arr, index, right, k);}}private static int selectPivot(int[] arr, int left, int right) {return arr[left];}private static int partition(int[] arr, int left, int right, int pivot) {int i = left;int j = right;while (i <= j) {while (arr[i] < pivot) {i++;}while (arr[j] > pivot) {j--;}if (i <= j) {swap(arr, i, j);i++;j--;}}return i;}private static void swap(int[] arr, int i, int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}
}

3. 拓展应用案例2:查找最大/最小值

快速选择算法也可以用于查找一个数组的最大/最小值。

3.1 步骤描述

  1. 定义一个方法 findMax,接受一个整型数组 arr 作为参数。
  2. 调用 quickSelect 方法,传入数组 arr、左边界 0、右边界 arr.length - 1 和最大值的位置 1
  3. quickSelect 方法中,选择基准元素 pivot,并调用 partition 方法进行分区。
  4. 根据 partition 方法的返回值 index,判断最大值的位置:
    • 如果 index 等于 1 - 1,则返回 arr[index]
    • 如果 index 大于 1 - 1,则递归调用 quickSelect 方法,在左半部分数组中查找最大值。
    • 如果 index 小于 1 - 1,则递归调用 quickSelect 方法,在右半部分数组中查找最大值。
  5. main 方法中,调用 findMax 方法,并打印最大值的值。

3.2 完整代码

public class QuickSelectMax {public static void main(String[] args) {int[] arr = {5, 3, 8, 2, 9, 1};int max = findMax(arr);System.out.println("最大值是:" + max);}private static int findMax(int[] arr) {return quickSelect(arr, 0, arr.length - 1, 1);}private static int quickSelect(int[] arr, int left, int right, int k) {int pivot = selectPivot(arr, left, right);int index = partition(arr, left, right, pivot);if (index == k - 1) {return arr[index];} else if (index > k - 1) {return quickSelect(arr, left, index - 1, k);} else {return quickSelect(arr, index, right, k);}}private static int selectPivot(int[] arr, int left, int right) {return arr[left];}private static int partition(int[] arr, int left, int right, int pivot) {int i = left;int j = right;while (i <= j) {while (arr[i] < pivot) {i++;}while (arr[j] > pivot) {j--;}if (i <= j) {swap(arr, i, j);i++;j--;}}return i;}private static void swap(int[] arr, int i, int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}
}

4.1 步骤描述

  1. 定义一个方法 findKthSmallest,接受一个整型数组 arr 和一个整数 k 作为参数。
  2. 调用 quickSelect 方法,传入数组 arr、左边界 0、右边界 arr.length - 1k
  3. quickSelect 方法中,选择基准元素 pivot,并调用 partition 方法进行分区。
  4. 根据 partition 方法的返回值 index,判断第k小的元素的位置:
    • 如果 index 等于 k - 1,则返回 arr[index]
    • 如果 index 大于 k - 1,则递归调用 quickSelect 方法,在左半部分数组中查找第k小的元素。
    • 如果 index 小于 k - 1,则递归调用 quickSelect 方法,在右半部分数组中查找第k小的元素。
  5. main 方法中,调用 findKthSmallest 方法,并打印第k小的元素的值。

4.2 完整代码

public class QuickSelectKthSmallest {public static void main(String[] args) {int[] arr = {5, 3, 8, 2, 9, 1};int k = 3;int kthSmallest = findKthSmallest(arr, k);System.out.println("第" + k + "小的元素是:" + kthSmallest);}private static int findKthSmallest(int[] arr, int k) {return quickSelect(arr, 0, arr.length - 1, k);}private static int quickSelect(int[] arr, int left, int right, int k) {int pivot = selectPivot(arr, left, right);int index = partition(arr, left, right, pivot);if (index == k - 1) {return arr[index];} else if (index > k - 1) {return quickSelect(arr, left, index - 1, k);} else {return quickSelect(arr, index + 1, right, k);}}private static int selectPivot(int[] arr, int left, int right) {return arr[left];}private static int partition(int[] arr, int left, int right, int pivot) {int i = left;int j = right;while (i <= j) {while (arr[i] < pivot) {i++;}while (arr[j] > pivot) {j--;}if (i <= j) {swap(arr, i, j);i++;j--;}}return i;}private static void swap(int[] arr, int i, int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}
}

在上面的代码中,我们查找数组 arr 中第3小的元素,即 k = 3。运行结果如下:

第3小的元素是:3

这个例子展示了快速选择算法在查找第k小的元素上的应用。通过快速选择算法,我们可以在平均时间复杂度为O(n)的情况下,快速找到第k小的元素。这对于大数据处理和数据挖掘等领域的应用非常有价值。

4. 结论

通过快速选择算法的拓展应用案例,我们可以看到该算法在查找中位数和查找最大/最小值等问题上的高效性和灵活性。通过手写实现和定制化,我们可以根据实际需求进行优化和改进,提高算法的效率和适用性。快速选择算法在大数据处理、机器学习、数据挖掘等领域有着广泛的应用前景。随着数据规模的不断增大和数据处理需求的不断增加,快速选择算法将发挥更加重要的作用。

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

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

相关文章

Java学习笔记——字符/字符串

在 Java 语言中&#xff0c;字符串都被设计成「不可变」的类型&#xff0c;即无法直接修改字符串的某一位字符&#xff0c;需要新建一个字符串实现 StringBuilder 字符 字符是用单引号括起来的单个字母&#xff0c;在Java中&#xff0c;表示字符的数据类型为char。一个字符…

GNU-ncurses库简介

文章目录 前言一、安装与使用二、ncurses库基本用法2.1 initscr()2.2 refresh()2.3 endwin() 三、初始化3.1 raw(), cbreak()3.2 echo() noecho()3.3 keypad()3.4 int halfdelay(int) 四、窗口机制简介五、输出函数六、输入函数七、输出修饰八、窗口机制总结 前言 ncurses是一…

mySQL 安装

一、windows安装包下载 mysql官网提供了两种安装方式&#xff0c;一个是zip安装&#xff0c;另一个是msi安装&#xff0c;这里简绍第一种安装方式&#xff0c;第二种简单&#xff0c;不再简绍 官网下载&#xff0c;根据自己需要选择版本&#xff1a;MySQL :: MySQL Community…

ReactNative中升级IOS 17版本Crash解决

ReactNative中升级IOS 17版本Crash解决 ReactNative中升级IOS 17版本Crash解决一、问题描述二、原因分析三、解决方案决策3.1 设置宽高为非零值3.2 使用新的UIGraphicsImageRenderer替换就版本的UIGraphicsBeginImageContext 四、可能使用到该API的三方库4.1 react-native-fast…

反转单链表

思路图1&#xff1a; 代码&#xff1a; struct ListNode* reverseList(struct ListNode* head){if(headNULL)//当head是空链表时 {return head; }struct ListNode* n1NULL;struct ListNode* n2head;struct ListNode* n3head->next;if(head->nextNULL)//当链表只有一个节…

高云FPGA系列教程(8):ARM串口数据接收(中断和轮询方式)

文章目录 [toc]1. GW1NSR-4C串口外设简介2. FPGA配置3. 常用函数4. 轮询方式接收数据5. 中断方式接收数据 本文是高云FPGA系列教程的第8篇文章。 本篇文章介绍片上ARM Cortex-M3硬核处理器串口外设的使用&#xff0c;演示轮询方式和中断方式接收串口数据&#xff0c;并进行回环…

如何搭建一个react项目(详细介绍)

要搭建一个基本的 React 项目&#xff0c;你需要执行以下步骤。在开始之前&#xff0c;请确保你已经安装了 Node.js 和 npm&#xff08;Node 包管理器&#xff09;。 搭建一个React项目 1&#xff0c;创建项目目录2&#xff0c;初始化项目3&#xff0c;安装 React 和 ReactDOM4…

安卓机型固件系统分区的基础组成 手机启动规律初步常识 各分区的基本含义与说明

此贴为基本常识。感兴趣的友友可以了解手机的启动顺序和各模式的基本操作与意义。另外了解手机系统分区各文件夹的含义 分区说明对应贴&#xff1a;安卓机型固件中分区对应说明 手机开机基本启动顺序 当我们按下手机开机键的时候。基本的启动顺序为 注意&#xff1a;该结构图…

交流耐压试验目的

试验目的 交流耐压试验是鉴定电力设备绝缘强度最有效和最直接的方法。 电力设备在运行中&#xff0c; 绝缘长期受着电场、 温度和机械振动的作用会逐渐发生劣化&#xff0c; 其中包括整体劣化和部分劣化&#xff0c;形成缺陷&#xff0c; 例如由于局部地方电场比较集中或者局部…

Facebook最佳聊单工具--SaleSmartly,智能回复+控评+群控分流

关于SaleSmartlySaleSmartly--全渠道客户沟通平台,它可以帮助企业实现聊天自动化、智能化&#xff0c;提高员工效率&#xff0c;降低人工成本&#xff0c;提升客服质量。 在管理facebook时&#xff0c;你遇到的痛点&#xff1a; &#xff08;1&#xff09;FB聊单如何实现业务最…

AUTOSAR汽车电子嵌入式编程精讲300篇-车载CAN总线网络的异常检测(续)

目录 车载 CAN 总线网络异常检测技术 3.1 车载 CAN 总线网络异常检测技术概述 3.1.1基于统计的异

7-3 成绩等级

7-3 成绩等级 给出一个成绩&#xff0c;要求输出成绩等级‘A’,‘B’,‘C’,‘D’,‘E’.(90分以上为’A’,80到89分为’B’,70到79分为’C’,60到69分为’D’,60分以下为’E’。 输入格式: 在一行输入一个整数n&#xff08;n<100)。 输出格式: 在一行中输出成绩相对应的等…

大麦订单生成器最新版 大麦订单一键生成截图

1.可以一键添加&#xff0c;生成的假订单没有水印&#xff0c;界面也很真实。 2.在软件中输入生成的信息&#xff0c;这是产品信息&#xff0c;选择生成的产品图像&#xff0c;最后生成它。 后台一键生成&#xff0c;独立后台管理 教程&#xff1a;解压源码&#xff0c;修改…

用于无功补偿的固定电容晶闸管控制反应器研究(Simulink)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

03MyBatis-Plus中的常用注解

常用注解 TableName MyBatis-Plus根据BaseMapper中指定的泛型(实体类型名)确定数据库中操作的表,如果根据实体类型名找不到数据库中对应的表则会报表不存在异常 //向表中插入一条数据 Test public void testInsert(){User user new User(null, "张三", 23, "…

深入学习 Redis Sentinel - 基于 DockerCompose 编排哨兵分布式架构,理解工作原理

目录 一、哨兵模式 1.1、为何引入哨兵模式 1.2、Redis Sentinel 分布式架构 1.2.1、概述 1.2.2、工作原理&#xff08;redis 哨兵的核心功能&#xff09; 1. 监控&#xff1a; 2. 自动故障转移&#xff1a; 3. 通知 1.2.3、问题&#xff1a;哨兵结点只有一个可以么&am…

SpringCloud——微服务

微服务技术栈 在之前的开发过程中&#xff0c;我们将所有的服务都部署在一台服务器中&#xff0c;当我们的服务开始越来越多&#xff0c;业务越来越复杂&#xff0c;当一台服务器不能承担我们的业务的时候&#xff0c;就需要将不同的业务分开部署在不同的服务器上&#xff0c;…

Feign实战-Springboot集成OpenFeign Demo以及参数详解

最近整理一下微服务的文章&#xff0c;先拿一直用的OpenFeign开刀 思考&#xff1a;微服务之间如何方便优雅的实现服务间的远程调用 一、说说openFeign是什么吧&#xff1f; 说到这个&#xff0c;那不得不先说说RPC 1.什么是RPC RPC 全称是 Remote Procedure Call &#x…

Appium混合页面点击方法tap的使用

原生应用开发&#xff0c;是在Android、IOS等移动平台上利用官方提供的开发语言、开发类库、开发工具进行App开发&#xff1b;HTML5&#xff08;h5&#xff09;应用开发&#xff0c;是利用Web技术进行的App开发。目前&#xff0c;市面上很多app都是原生和h5混合开发&#xff0c…

消息队列常见问题

什么是消息队列&#xff1f;请简要解释消息队列的工作原理。 答&#xff1a;消息队列是一种异步通信机制&#xff0c;用于在应用程序之间传递消息。它主要包括生产者&#xff08;Producer&#xff09;、消息队列&#xff08;Message Queue&#xff09;和消费者&#xff08;Con…