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

数据结构与算法:排序算法(2)

目录

堆排序

使用步骤

代码实现

计数排序

适用范围

过程

代码实现

排序优化

桶排序

工作原理

代码实现


堆排序

二叉堆的特性:

        1. 最大堆的堆顶是整个堆中的最大元素

        2. 最小堆的堆顶是整个堆中的最小元素

        以最大堆为例,如果删除一个最大堆的堆顶(并不是完全删除,而是跟末尾的节点交换位置),经过自我调整,第2大的元素就会被交换上来,成为最大堆的新堆顶

        在删除值为10的堆顶节点后,经过调整,值为9的新节点就会顶替上来;由于二叉堆的这个特性,每一次删除旧堆顶,调整后的新堆顶都是大小仅次于旧堆顶的节点。那么只要反复删除堆顶,反复调整二叉堆,所得到的集合就会成为一个有序集合。

使用步骤

1. 把无序数组构建成二叉堆。需要从小到大排序,则构建成最大堆;需要从大到小排序,则构建成最小堆

2. 循环删除堆顶元素,替换到二叉堆的末尾,调整堆产生新的堆顶

代码实现

public static void main(String[] args){int[] array = new int[] {4,4,6,5,3,2,8,1,7,5,6,0,10};heapSort(array);System.out.println(Arrays.toString(array));}public static void downAdjust(int[] array, int parentIndex, int length) {int temp = array[parentIndex];int childIndex = 2 * parentIndex + 1;while (childIndex < length){if (childIndex + 1 < length && array[childIndex + 1] > array[childIndex]) {childIndex++;}if (temp >= array[childIndex]){break;}array[parentIndex] = array[childIndex];parentIndex = childIndex;childIndex = 2 * childIndex + 1;}array[parentIndex] = temp;}public static void heapSort(int[] array) {//1.无序数组构建成最大堆for (int i = (array.length-2)/2; i >= 0; i--) {downAdjust(array, i, array.length);}System.out.println(Arrays.toString(array));//2.环删除堆顶元素,移到集合尾部,调整堆产生新的堆顶for (int i = array.length - 1; i > 0; i--) {int temp = array[i];array[i] = array[0];array[0] = temp;downAdjust(array, 0, i);}}

计数排序

有一些特殊的排序并不基于元素比较,而是利用数组下标来确定元素的正确位置的。

适用范围

它适用于一定范围内的整数排序。在取值范围不是很大的情况下,它的性能甚至快过那些时间复杂度为O(nlogn)的排序

过程

假设数组中有20个随机整数,取值范围为0~10,要求用最快的速度把这20个整数从小到大进行排序,可以根据这有限的范围,建立一个长度为11的数组。数组下标从0到10,元素初始值全为0

随机值:9,3,5,4,9,1,2,7,8,1,3,6,5,3,4,0,10,9 ,7,9

这个无序的随机数列,每一个整数按照其值对号入座,同时,对应数组下标的元素进行加1操作

该数组中每一个下标位置的值代表数列中对应整数出现的次数;直接遍历数组,输出数组元素的下标值,元素的值是几,就输出几次,输出的数列已经是有序的了

代码实现

public static void main(String[] args){int[] array = new int[] {4,4,6,5,3,2,8,1,7,5,6,0,10};int[] sortedArray = countSort(array);System.out.println(Arrays.toString(sortedArray));}public static int[] countSort(int[] array) {//1.得到数列的最大值int max = array[0];for(int i=1; i<array.length; i++){if(array[i] > max){max = array[i];}}//2.根据数列最大值确定统计数组的长度int[] countArray = new int[max+1];//3.遍历数列,填充统计数组for(int i=0; i<array.length; i++){countArray[array[i]]++;}//4.遍历统计数组,输出结果int index = 0;int[] sortedArray = new int[array.length];for(int i=0; i<countArray.length; i++){for(int j=0; j<countArray[i]; j++){sortedArray[index++] = i;}}return sortedArray;}

排序优化

只以数列的最大值来决定统计数组的长度,其实并不严谨;如:数列的最大值是99,但最小的整数是90。如果创建长度为100的数组,那么前面从0到89的空间位置就都浪费了

解决:

        以数列最大值-最小值+1作为统计数组的长度

同时,数列的最小值作为一个偏移量,用于计算整数在统计数组中的下标

public static void main(String[] args){int[] array = new int[] {4,4,6,5,3,2,8,1,7,5,6,0,10};int[] sortedArray = countSort(array);System.out.println(Arrays.toString(sortedArray));}public static int[] countSort(int[] array) {//1.得到数列的最大值和最小值,并算出差值dint max = array[0];int min = array[0];for(int i=1; i<array.length; i++){if(array[i] > max){max = array[i];}if(array[i] < min){min = array[i];}}int d = max - min;//2.创建统计数组并统计对应元素的个数int[] countArray = new int[d+1];for(int i=0; i<array.length; i++){countArray[array[i]-min]++;}//3.统计数组做变形,后面的元素等于前面的元素之和for(int i=1;i<countArray.length;i++) {countArray[i] += countArray[i-1];}//4.遍历统计数组,输出结果int[] sortedArray = new int[array.length];for(int i=array.length-1;i>=0;i--) {sortedArray[countArray[array[i]-min]-1]=array[i];countArray[array[i]-min]--;}return sortedArray;}

桶排序

桶排序是一种线性时间的排序算法。类似于计数排序所创建的统计数组,桶排序需要创建若干个桶来协助排序。

桶:每一个桶(bucket)代表一个区间范围,里面可以承载一个或多个元素。

工作原理

1.创建桶,并确定每一个桶的区间范围

        创建的桶数量等于原始数列的元素数量

        区间跨度 = (最大值-最小值)/ (桶的数量 - 1)

2.遍历原始数列,把元素对号入座放入各个桶中

3.对每个桶内部的元素分别进行排序

4.遍历所有的桶,输出所有元素

代码实现

public static void main(String[] args){double[] array = new double[]{4.12,6.421,0.0023,3.0,2.123,8.122,4.12, 10.09};double[] sortedArray = bucketSort(array);System.out.println(Arrays.toString(sortedArray));}public static double[] bucketSort(double[] array){//1.得到数列的最大值和最小值,并算出差值ddouble max = array[0];double min = array[0];for(int i=1; i<array.length; i++) {if(array[i] > max){max = array[i];}if(array[i] < min){min = array[i];}}double d = max - min;//2.初始化桶int bucketNum = array.length;ArrayList<LinkedList<Double>> bucketList = new ArrayList<LinkedList<Double>>(bucketNum);for(int i=0;i<bucketNum;i++){bucketList.add(new LinkedList<Double>());}//3.遍历原始数组,将每个元素放入桶中for(int i = 0; i < array.length; i++){int num = (int)((array[i] - min) * (bucketNum-1) / d);bucketList.get(num).add(array[i]);}//4.对每个桶内部进行排序for(int i = 0; i < bucketList.size(); i++){Collections.sort(bucketList.get(i));}//5.输出全部元素double[] sortedArray = new double[array.length];int index = 0;for(LinkedList<Double> list : bucketList){for(double element : list){sortedArray[index] = element;index++;}}return sortedArray;}

        所有的桶都保存在ArrayList集合中,每一个桶都被定义成一个链表(LinkedList<Double>),这样便于在尾部插入元素

相关文章:

数据结构与算法:排序算法(2)

目录 堆排序 使用步骤 代码实现 计数排序 适用范围 过程 代码实现 排序优化 桶排序 工作原理 代码实现 堆排序 二叉堆的特性&#xff1a; 1. 最大堆的堆顶是整个堆中的最大元素 2. 最小堆的堆顶是整个堆中的最小元素 以最大堆为例&#xff0c;如果删除一个最大堆的…...

1_图神经网络GNN基础知识学习

文章目录 安装PyTorch Geometric安装工具包 在KarateClub数据集上使用图卷积网络 (GCN) 进行节点分类两个画图函数Graph Neural Networks数据集&#xff1a;Zacharys karate club network.PyTorch Geometric数据集介绍 edge_index使用networkx可视化展示 Graph Neural Networks…...

瑞芯微:基于RK3568的ocr识别

光学字符识别&#xff08;Optical Character Recognition, OCR&#xff09;是指对文本资料的图像文件进行分析识别处理&#xff0c;获取文字及版面信息的过程。亦即将图像中的文字进行识别&#xff0c;并以文本的形式返回。OCR的应用场景 卡片证件识别类&#xff1a;大陆、港澳…...

C++真的是 C加加

&#x1f4dd;个人主页&#xff1a;夏目浅石. &#x1f4cc;博客专栏&#xff1a;C的故事 &#x1f3e0;学习社区&#xff1a;夏目友人帐. 文章目录 前言Ⅰ. 函数重载0x00 重载规则0x01 函数重载的原理名字修饰 Ⅱ. 引用0x00 引用的概念0x01 引用和指针区分0x03 引用的本质0x04…...

java学习--day5 (java中的方法、break/continue关键字)

文章目录 day4作业今天的内容1.方法【重点】1.1为什么要有方法1.2其实已经见过方法1.3定义方法的语法格式1.3.1无参无返回值的方法1.3.2有参无返回值的方法1.3.3无参有返回值的方法1.3.4有参有返回值的方法 2.break和continue关键字2.1break;2.2continue; 3.案例关于方法的练习…...

MFC主框架和视类PreCreateWindow()函数学习

在VC生成的单文档应用程序中&#xff0c;主框架类和视类均具有PreCreateWindow函数&#xff1b; 从名字可知&#xff0c;可在此函数中添加一些代码&#xff0c;来控制窗口显示后的效果&#xff1b; 并且它有注释说明&#xff0c; Modify the Window class or styles here by…...

for forin forof forEach map区别

一、总结 相同点&#xff1a;都是串行遍历。不同点&#xff1a; 二、for of循环 设计目的&#xff1a;遍历所有数据结构的统一方法。原理&#xff1a;会调用数据结构的Symbol.iterator方法。 只要数据结构定义了Symbol.iterator属性&#xff0c;就能用for of遍历它的成员。…...

特殊时间(蓝桥杯)

特殊时间 问题描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 2022年2月22日22:20 是一个很有意义的时间, 年份为 2022 , 由 3 个 2 和 1 个 0 组成, 如果将月和日写成 4 位, 为 0222 , 也是由 3 个 2 和 1 个 0 组 成…...

VUE路由与nodeJS环境搭建

VUE路由 Vue路由是Vue.js提供的路由管理工具&#xff0c;它允许我们在应用程序中实现页面之间的导航&#xff0c;从而使单页面应用程序的开发更加方便。通过Vue路由&#xff0c;我们可以轻松地创建和管理多个视图&#xff0c;并在这些视图之间导航。 Vue路由使用HTML5的Histo…...

抗锯齿的线

抗锯齿的线 右下角的时候h是0,到顶部 h是1&#xff0c;然后中间y相距4个像素&#xff0c;那dy就是0.25 如果让h abs(fract(h - 0.5) - 0.5) 中间一行0.5&#xff0c;第一行 第三行都是0.25&#xff0c;两端都是0 根据插值来看 这里是 如果用h/dy 那么第一行以上&#xff0…...

如何使用高压放大器驱动高容性负载

使用高压放大器驱动高容性负载是一个具有挑战性的任务&#xff0c;需要仔细考虑电路设计和操作技巧。下面西安安泰Aigtek将为您介绍一些关于如何使用高压放大器驱动高容性负载的方法和注意事项。 首先&#xff0c;让我们了解一下高容性负载。高容性负载通常指电容值较大的负载元…...

kubernetes集群证书过期启动失败问题解决方法

1、问题现象 执行kubectl命令异常报告 [rootk8s-master1 ~]# kubectl get node The connection to the server 192.168.227.131:6443 was refused - did you specify the right host or port? [rootk8s-master1 ~]# 查看etcd的日志&#xff0c;报错信息如下 {"level&…...

nvm使用的注意事项和常用命令。

nvm官网下载地址&#xff1a;nvm文档手册 - nvm是一个nodejs版本管理工具 - nvm中文网 (uihtm.com) 参考网址&#xff1a;(14 封私信 / 80 条消息) 如何通过 nvm 安装多版本 nodejs&#xff1f;npm 安装失败了怎么办&#xff1f; - 知乎 (zhihu.com) nvm目录下&#xff0c;修…...

代码大全阅读随笔(七)

循环控制 循环控制会出现什么样的错误&#xff0c;任何一种答案都可以归结到下面所说的问题之一&#xff1a;忽略或者错误的对循环执行初始化&#xff0c;忽略了对累加变量或者其他与循环有关变量执行初始化&#xff0c;不正确的嵌套&#xff0c;不正确的循环终止&#xff0c;忽…...

用户与权限管理

文章目录 用户与权限管理1. 用户管理1.1 MYSQL用户1.2 登录MySQL服务器1.3 创建用户1.4 修改用户1.5 删除用户1.6 修改密码1. 修改当前用户密码2. 修改其他用户密码 1.7 MYSQL8密码管理 2. 权限管理2.1 权限列表2.2 授予权限的原则2.3 授予权限2.4 查看权限2.5 收回权限 3. 权限…...

mysql集群使用nginx配置负载均衡

参考链接&#xff1a;https://mu-sl.com//archives/mysql%E9%9B%86%E7%BE%A4%E4%BD%BF%E7%94%A8nginx%E9%85%8D%E7%BD%AE%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1 配置文件nginx_tcp.conf 示例 load_module modules/ngx_stream_module.so;stream{upstream tcpssh{hash $remote_…...

蓝桥杯每日一题2023.9.21

蓝桥杯2021年第十二届省赛真题-异或数列 - C语言网 (dotcpp.com) 题目描述 Alice 和 Bob 正在玩一个异或数列的游戏。初始时&#xff0c;Alice 和 Bob 分别有一个整数 a 和 b&#xff0c;有一个给定的长度为 n 的公共数列 X1, X2, , Xn。 Alice 和 Bob 轮流操作&#xff0…...

知识联合——函数指针数组

前言&#xff1a;小伙伴们又见面啦&#xff0c;今天我们来讲解一个将函数&#xff0c;指针&#xff0c;数组这三个C语言大将整合在一起的知识——函数指针数组。同时来告诉小伙伴们我们上一篇文章的伏笔——函数指针的具体用法。 目录 一.什么是函数指针数组 二.函数指针数组…...

【Nginx26】Nginx学习:日志与镜像流量复制

Nginx学习&#xff1a;日志与镜像流量复制 总算到了日志模块&#xff0c;其实这个模块的指令之前我们就用过了&#xff0c;而且也是是非常常见的指令。相信这一块的学习大家应该不会有什么难度。另一个则是镜像功能&#xff0c;这个估计用过的同学就比较少了&#xff0c;不过也…...

Stability AI发布基于稳定扩散的音频生成模型Stable Audio

近日Stability AI推出了一款名为Stable Audio的尖端生成模型&#xff0c;该模型可以根据用户提供的文本提示来创建音乐。在NVIDIA A100 GPU上Stable Audio可以在一秒钟内以44.1 kHz的采样率产生95秒的立体声音频&#xff0c;与原始录音相比&#xff0c;该模型处理时间的大幅减少…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...