使用Kotlin实现Java的优先队列PriorityQueue

前言

上周在面试时,偶然一个算法用到了优先队列思想。我只懂效果不懂实现,当时感觉和堆排序的思想差不多。今天深入源码,自己又实现一遍加深印象。

源码有什么

  1. 具有Queue和Collection集合和Queue队列的性质
  2. 可以保证每次取出的元素都是最值(默认是最小,可以自己设置)
  3. 内部采用推排序思想,上浮siftUp和下沉siftDown
  4. 存储采用可变数组(和ArrayList一样),默认大小是11,刚开始每次*2+2,后面每次加一半(size+=size>>2)

如何实现一个优先队列

  1. 队列最基本的offer,peek,poll
  2. 集合最基本的isEmpty,toString,size
  3. 供内部使用的siftUp,siftDown,grow

代码实现

个人有写算法加注释的习惯,看不懂私聊

import java.util.*
import kotlin.math.maxfun main() {val queue = MyPriorityQueue().apply {repeat(10) {offer(Random().nextInt(100))}}while (queue.isNotEmpty()) {println(queue.poll())}
}class MyPriorityQueue {// 保存元素,方便实现泛型,默认大小是11private var array = Array(11) { 0 }// 当前数目private var size = 0// 增fun offer(value: Int) {if (size == array.size) {grow(size + 1)}array[size++] = valuesiftUp(size - 1, value)}// 看队头fun peek(): Int {return if (size == 0) -1 else array[0]}// 取对头fun poll(): Int {if (size == 0) {return -1}val result = array[0]array[0] = array[size - 1]size--siftDown(0, array[0])return result}// 没有size方法fun size() = size// 没有isEmpty方法fun isEmpty() = size == 0fun isNotEmpty() = size > 0// 上浮,默认最小在上面private fun siftUp(index: Int, value: Int) {// 在上面选个大的和当前交换,没有退出var i = indexwhile (i > 0) {val parent = (i - 1) / 2if (array[parent] <= value) {break}array[i] = array[parent]i = parent}array[i] = value}// 下沉,默认最大在下面private fun siftDown(index: Int, value: Int) {// 选出子节点最小的一个,没有则退出var i = index// 当至少存在左子节点时while (i * 2 + 1 < size) {// 找出最小的子节点下标val minChild = if (i * 2 + 2 >= size || array[i * 2 + 1] <= array[i * 2 + 2]) i * 2 + 1 else i * 2 + 2// 如果最小的还是比父节点大,退出if (array[minChild] >= value) {break}array[i] = array[minChild]i = minChild}array[i] = value}// 扩容机制,小于64,*2+2,大于,+>>2private fun grow(minCapacity: Int) {var newCapacity = array.size + if (array.size < 64) array.size + 2 else array.size / 2// 在一次添加大量元素才可能用到newCapacity = max(newCapacity, minCapacity)array = Arrays.copyOf(array, newCapacity)}// 重写toString方法override fun toString() = StringBuilder().apply {append("[")for (i in 0 until size) {append(if (i == 0) array[i] else " ${array[i]}")}append("]")}.toString()
}

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

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

相关文章

pandas数据分析40——读取 excel 合并单元格的表头

案例背景 真的很容易疯....上班的单位的表格都是不同的人做的&#xff0c;所以就会出现各种合并单元格的情况&#xff0c;要知道我们用pandas读取数据最怕合并单元格了&#xff0c;因为没规律...可能前几列没合并&#xff0c;后面几列又合并了....而且pandas对于索引很严格&am…

vue3的setup中的那些操作

setup中的那些操作 第一&#xff0c;setup中没有this <script setup>import { ref } from vueconst divRef ref(null)divRef.value</script>这里的ref(null)&#xff0c;ref用来创建一个支持vue的响应式数据&#xff0c;会将divRef用vue的Watcher处理一遍&#…

地球IT

地球是我们生活的家园&#xff0c;也是人类发展的基地。地球不仅仅是一个行星&#xff0c;更是一个复杂而有机的生态系统。 地球直径约为12,742公里&#xff0c;被称为“蓝色星球”&#xff0c;因为它的表面约70%被水覆盖。海洋是地球上最大的生态系统之一&#xff0c;它们扮演…

JavaScript对象知识总结

一、创建对象的三种方式 1、字面量创建对象 2、new关键字&#xff0b;构造函数创建对象 3、Object.create()创建对象 二、查看对象属性和更改对象值的两种方式 1、形如&#xff1a;obj.keyvalue 2、形如&#xff1a;obj[key]value 三、删除对象属性 1、delete obj.key …

计算机竞赛 图像检索算法

文章目录 1 前言2 图像检索介绍(1) 无监督图像检索(2) 有监督图像检索 3 图像检索步骤4 应用实例5 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 图像检索算法 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff…

【数理知识】向量的坐标基表示法,Matlab 代码验证

序号内容1【数理知识】向量的坐标基表示法&#xff0c;Matlab 代码验证2【数理知识】向量与基的内积&#xff0c;Matlab 代码验证 文章目录 1. 向量的坐标基表示2. 二维平面向量举例3. Matlab 代码验证Ref 1. 向量的坐标基表示 假设空间中存在一个向量 a ⃗ \vec{a} a &#…

多线程 + 队列 + 进程锁 + 广度优先搜索 + 布隆过滤器,通过好友获取所有用户

语言&#xff1a;python 库&#xff1a; threading queue pybloom_live import threading import queue import requests from pybloom_live import BloomFilter import one_friend_data # 获取单个用户信息# 创建布隆过滤器 bloom BloomFilter(capacity200000000, error_ra…

Vite更新依赖缓存失败,强制更新依赖缓存

使用vitets开发一段时间了&#xff0c;感觉并不是想象中的好用&#xff0c;特别是出现些稀奇古怪的问题不好解决&#xff0c;比如下面这个问题 上午9:50:08 [vite] error while updating dependencies: Error: ENOENT: no such file or directory, open E:/workspace-dir/node…

ansible(1)-- 部署ansible连接被控端

目录 一、部署ansible 1.1 安装 1.2 测试连接 192.168.136.55 ansible 192.168.136.56被控端 一、部署ansible 1.1 安装 zabbix-s只是主机名&#xff0c;不用在意&#xff0c;更好该主机也安装了zabbix&#xff0c;不好更改。 下载阿里云epel源 #安装阿里云的epel源&#…

计算机网络(9) --- 数据链路层与MAC帧

计算机网络&#xff08;8&#xff09; --- IP与IP协议_哈里沃克的博客-CSDN博客IP与IP协议https://blog.csdn.net/m0_63488627/article/details/132155460?spm1001.2014.3001.5502 目录 1.MAC帧 1.MAC地址 2.MAC帧报头 3.资源碰撞 4.MTU 1.对IP协议的影响 2.对UDP协议…

esp8266+电压检测模块检测电池电压

请注意 esp8266的ADC引脚受wifi模块影响&#xff0c;会导致不准确&#xff0c;具体请查看这里&#xff1a;https://github.com/esp8266/Arduino/issues/2070 简单说一下解决方案&#xff1a; ①如果不是频繁的读取数据&#xff0c;可以在wifi连接前读取数据然后存储到缓存&…

【Visual Studio Code】--- Win11 配置 VS Code 为中文 超详细

Win11 配置 VS Code 为中文 超详细 一、概述二、重要提示二、配置 VS Code 为中文 一、概述 一个好的文章能够帮助开发者完成更便捷、更快速的开发。书山有路勤为径&#xff0c;学海无涯苦作舟。我是秋知叶i、期望每一个阅读了我的文章的开发者都能够有所成长。 二、重要提示…

React Native 文本输入基础知识

在 React Native 中提供了一个文本输入组件TextInput。此组件主要是监听键盘输入事件&#xff0c;并把对应的输入值显示在组件中&#xff0c;此组件还提供了很多功能配置参数&#xff0c;例如自动更正、自动大写、占位符文本和不同的键盘类型&#xff08;例如数字键盘&#xff…

RT-Thread 的环形缓冲区 ---- 镜像指示位

可以看一下这篇我写的博客&#xff0c;了解一下大概&#xff1a; RingBuffer 环形缓冲区----镜像指示位_呵呵哒(&#xffe3;▽&#xffe3;)"的博客-CSDN博客https://blog.csdn.net/weixin_41987016/article/details/132340883?spm1001.2014.3001.5501 【回顾】缓冲区…

Mock平台-08开发:项目管理(四)编辑功能和Component抽离

【Mock平台】为系列测试开发教程&#xff0c;从0到1编码带你一步步使用Spring Boot 和 Antd React框架完成搭建一个测试工具平台&#xff0c;希望作为一个实战项目对各位的测试开发学习之路有帮助&#xff0c;大奇一个专注测试技术干货原创与分享的家伙。 本篇重点&#xff1a;…

MetaMask Mobile +Chrome DevTools 调试Web3应用教程

注&#xff1a;本教程来源网络&#xff0c;根据项目做的整理 写好了WEB3应用&#xff0c;在本地调试用得好好的&#xff0c;但是用钱包软件访问就报莫名的错&#xff0c;但是又不知道是什么原因&#xff0c;排查的过程非常浪费时间 。 因此在本地同一局域网进行调试就非常有必要…

mybatis-plus--配置-(sql)日志输出-自动填充-分页-多数据源-逻辑删除

写在前面&#xff1a; 本文主要介绍mybatis-plus的配置&#xff0c;以后在有的时候在补充。欢迎交流。 文章目录 日志输出自动填充分页全局字段配置多数据源 日志输出 调试的时候需要看执行的sql&#xff0c;这时候就很需要日志来记录查看了。 mybatis-plus的日志配置在yml…

Python爬虫——scrapy_读书网数据入库和链接跟进

数据入库 先创建一个数据库 create table book(id int primary key auto_increment,name varchar(128),src varchar(128));settings.py DB_HOST 169.254.38.183 # 端口号是一个整数 DB_PORT 3306 DB_USER root DB_PASSWORD 123456 # 数据库名称 DB_NAME spider01 DB_CHA…

软件建模的4个视图

逻辑视图 元素&#xff1a;类和包。 关系&#xff1a;它们之间的关系。 用途&#xff1a;说明人、事、物、规则是如何分类的。 进程视图 元素&#xff1a;进程。 关系&#xff1a;进程间通信。 用途&#xff1a;说明进程的详细组织结构&#xff0c;其中包含类和子系统到进程和…