排序算法(3)—优先队列,堆排序

【每日算法】堆排序&优先队列 堆排序(heapsort)的运行时间为O(n logn),是一种原地排序算法,是不稳定的排序算法。堆基本介绍先直观感受一下,下面就是一个堆:16 7 3 20 17 8什么??上面不就一个数组吗……?!没错,(二叉)堆数据结构是一种数组对象。不过,让我们用另外一种方式来看这个数组:对于表示堆的数组arr[1…n],我们以arr[1]为根,给定某个节点下标i,令其父节点和左右后代节点的下标为:pare 阅读详情

本文主要讨论基于二叉堆数据结构的优先队列的实现以及衍生的堆排序
实现优先队列还可以使用栈,队列等数据结构,在此略
文章最后附有堆排序完整代码

优先队列

1. 主要解决问题

有时候比不需要元素全部有序,操作时,我们可能只需要处理最大(最小)的元素
二叉堆的优先队列主要是高效(对数级别)实现删除最大元素,和插入元素操作。

对于其他数据结构的优先队列的实现:队列(删除最古老元素)以及栈(删除最新元素)类似

2. 二叉堆的概念

 1).当二叉树的每个节点都小于它的父结点,则称为堆有序。
 2).二叉堆中,位置为k的结点,父结点为不大于k/2的整数,子结点为2k和2k+1
 3).一颗大小为N的二叉树的高度不大于lgN的整数。

3. 二叉堆的两个重要操作

1).由上至下的堆有序化(上浮)
堆的有序状态因为某个结点变得比他的父结点更大,而打破有序状态,则需要交换它与它的父结点来重新实现有序堆。

    private void swim(int k)
    {
        while(k>1 && less(k/2,k))
        {
            exch(k/2,k); //交换arr[k/2]和arr[k]元素位置
            k = k/2;     //第一次比较交换后,后面的结点仍要交换
        }
    }

2).由下至上的堆有序化(下沉)
堆的有序状态因为某个结点比它的子结点更小而打破,则需要交换它与它的子结点中较大来实现有序堆。

    private void sink(int k)
    {
        while(2*k<=N)
        {
            int j = 2*k;
            if(j<N && less(j,j+1))
                j++;
            if(!less(k,j))
                break;
            exch(k,j);
            k = j;
        }
    }

4. 基于二叉堆的优先队列实现

1).插入元素
将新元素添加到数组末尾,增加堆的大小,并让这个新元素上浮到合适位置。

    public void insert(T v)
    {
        arr[++N] = v;
        swim(N);
    }

2).删除最大元素
从数组的顶端删除最大元素,并将,并且将堆中最后一个元素放到顶端(此时有序堆被打破),减小堆大小,并让这个元素下沉到合适位置。

    public T delMax()
    {
        T del = arr[1];
        exch(1,N--);
        arr[N+1] = null; //防止对象游离
        sink(1);
        return del;
    }

复杂度
对于一个含有N个元素的堆优先队列,插入元素不超过(lgN+1)次比较
删除元素的操作不超过2lgN次比较

5. 堆排序

    **1).思想:**
 将原始数组重新组织放进堆中,在下沉排序阶段,按递减顺序一次取得元素并得到排序结果
 **2).实现:**
    public static void HeapSort(Comparable[] arr)
    {
        int N = arr.length;
        for(int k = N/2; k>=1; k--)
            sink(arr,k,N);
        while(N>1)
        {
            Hexch(arr,1,N--);
            sink(arr,1,N);
        }
    }

3).复杂度:
时间复杂度:NlogN
空间复杂度:1
4).堆排序特点:
目前所知的唯一同时最优利用时间和空间的排序方法—最坏的情况下也能保证使用~NlgN次比较的额外空间。
所以堆排序适用于空间十分紧张的时候(嵌入式系统等)。
堆排序完整代码:

package sort;
/**
  * @author : luoz
  * @date time:2016年9月4日 上午12:10:48 
**/
public class HeapSort {

    //数组索引从零开始,而二叉树从1开始,所以传入参数-1,下同.
    private static boolean Hless(Comparable[] a,int i,int j)
    {
        return a[i-1].compareTo(a[j-1])<0;
    }

    private static void Hexch(Comparable[] a,int i,int j)
    {
        Comparable t = a[i-1];
        a[i-1] = a[j-1];
        a[j-1] = t;
    }

    //sink()以a[],N作为参数,其他不变.
    private static void sink(Comparable[] a,int k,int N)
    {
        while(2*k <= N)
        {
            int j = 2*k;
            if(j<N && Hless(a,j,j+1)) 
                j++;
            if(!Hless(a,k,j))
                break;          
            Hexch(a,k,j);
            k = j;
        }
    }
    /**
     * 传入数组arr,N为数组长度.  
     * @param arr
     */
    public static void heapSort(Comparable[] arr)
    {
        int N = arr.length;
        for(int k = N/2; k>=1; k--)
            sink(arr,k,N);
        while(N>1)
        {
            Hexch(arr,1,N--);
            sink(arr,1,N);
        }
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Comparable[] HeapArray = {"A","C","E","D","K","Z"};     
        heapSort(HeapArray);        
        for(Comparable a : HeapArray)
            System.out.println(a);      
    }

}

算法第四版


内容原创,转载注明出处
算法之Java优先队列与排序的深入探索及应用 在编程的学习过程中,掌握算法和数据结构是提升能力的关键所在。今天,我们一同深入研究Java中的优先队列和排序算法,从基础概念、实现方式到实际应用,希望能和大家共同进步,让我们在算法的世界里探索得更深更远! 阅读详情

相关推荐

优先队列的实现与堆排序算法

优先队列的实现使用最大堆作为优先队列的一种实现方式。演示了如何插入元素和提取最大元素的操作。堆排序算法通过构建最大堆实现排序过程。分析了堆排序的时间复杂度、空间复杂度以及其在大数据量排序中的优势。应用场景与性能分析讨论了堆排序在不同领域中的实际应用,如操作系统调度、图形学和数据库等。性能比较和选择适当排序算法的建议。算法的稳定性和可扩展性堆排序是一种不稳定排序算法,适用于大规模数据的排序需求。强调了根据实际情况选择合适排序算法的重要性。

一键难忘的博客 4401

一步步地分析排序——优先队列和堆排序

本文框架 定义和使用场景 优先队列是一个抽象数据类型,和栈、队列类似,它们都是抽象数据类型,相当于一个Java类,有自己的属性,并对外提供API。在了解它有什么API之前,先来看看优先队列的使用场景。 优先队列适用于需要对集合不断地执行插入元素、删除最大(或最小)元素的场景。这个场景大体可以分为两类: 第一类是业务实际情况需要,比如CPU的任务调度,待执行的任务是一个集合,每启动一个新程序就是在...

Kingfar Ou 1680

【JavaScript 算法】堆排序:优先队列的实现

堆排序(Heap Sort)是一种基于堆数据结构的排序算法,具有较好的时间复杂度表现。堆是一种特殊的完全二叉树,分为最大堆和最小堆。堆排序通过构建最大堆或最小堆来实现排序过程。本文将详细介绍堆排序算法的原理、实现及其应用。

Allen- 1432

算法 —— 排序 —— 优先队列

优先队列 二叉堆 优先队列 【Priority Queue】 首先声明一下,优先队列是基于堆的完全二叉树,它和队列的概念无关。(它并不是队列,而是树) 并且,优先队列最重要的操作就是: 删除最大元素和插入元素,所以我们把精力集中在这两点上。(本文以最大堆为主讲述) 二叉堆...

凶残的程序员 6664

Abaqus6.14.4 Linux详细图文安装教程

Abaqus6.14.4 Linux详细图文安装教程 20170409 1. 准备安装环境 1.1 安装CentOS 6.5,更新库 1.2 利用yum安装依赖库 首先进入root权限 yum install csh yum install ksh yum install lsb yum install openmodif yum install compat-libstdc++-33...

snuhxm的博客 7844

PostgreSQL+Citus分布式集群实战:从零搭建到性能调优

本文详细介绍了如何从零开始搭建并优化PostgreSQL+Citus分布式数据库集群。内容涵盖集群规划、源码编译安装、Citus扩展部署、节点配置、分布式表创建以及核心性能调优策略,为应对海量数据增长提供了完整的部署指南和实战解决方案。

oo7890的博客 629

【数据结构】基础算法:排序——优先队列的原理与实现

优先队列 优先级队列为,首部元素最大,总是删除当前最大元素。并在尾部插入元素。 优先队列的两种操作:删除最大元素和插入元素。 优先队列的一些重要的应用场景包括: 模拟系统,其中事件的键即为发生的时间,而系统需要按照时间顺序处理所有事件; 任务调度,其中键值对应的优先级决定了应该首先执行哪些任务; 数值计算,键值代表计算错误,而我们需要按照键值指定的顺序来修正它们。 堆排序,通过插入一列元素然后一个个地删掉其中最小的元素,我们可以用优先队列实现排序算法。 初级实现 4种基础数据结构:有序或无序的数组

weixin_42033436的博客 3192

从DC到DCG:手把手教你搭建物理感知综合流程(含DEF文件处理避坑指南)

本文详细介绍了从Design Compiler(DC)过渡到DC Topographical(DCT)和DC Graphical(DCG)的完整操作框架,特别针对DEF文件处理提供避坑方案。通过环境准备、工具升级、DEF文件处理、DCG综合配置等步骤,帮助开发者高效应对28nm以下工艺节点的物理感知综合挑战,显著提升时序收敛效率。

weixin_27966471的博客 381

优先队列priority_queue的排序(c++版贼全一看就会)

cmp必须为类,然后重载内部的比较函数,比较函数的内部与通常的cmp写法一样//根据first升序,second降序int main()a.push(d);a.push(c);a.push(b);while (!输出1 31 22 5int x;int y;/*friend bool operator > (const node& a, const node& b) //法一,这里是小根堆,有greater,要重载大于号。

2201_75385857的博客 5272

从solidworks导出URDF模型

一、下载sw_urdf_exporter插件 ROS目前提供了SolidWorks转URDF的插件,叫做sw_urdf_exporter,从http://wiki.ros.org/sw_urdf_exporter下载sw2urdfSetup.exe文件,下载后点击安装,安装完成后就能在solidworks中导出URDF模型了。 二、创建solidworks模型 下面以较为简单的四轮小车为例进行说...

weixin_45168199的博客 4万+

【YOLO 系列】基于YOLOv8的工业零件表面缺陷智能检测系统【python源码+Pyqt5界面+数据集+训练代码】

本文详细介绍了如何基于YOLOv8深度学习模型和PyQt5图形界面,构建一套完整的工业零件表面缺陷智能检测系统。内容涵盖从环境搭建、数据集标注、模型训练调参到最终封装成可执行桌面软件的全流程,并深入解析了YOLOv8在工业视觉场景中的技术优势与落地优化策略。

ol78901234的博客 402

数据结构与算法——优先队列

一、优先队列 优先队列按照队列的方式正常入队,但按照优先级出队。有两种实现方式:堆(二插堆、多项式堆等等)和二叉搜索树 数据流中的第k大元素 leetcode第703题 ...

贾维斯的小屋 780

uniapp串口通信实战:从零搭建物联网设备控制App(附完整代码)

本文详细介绍了如何使用Uniapp实现串口通信,从零搭建物联网设备控制App。内容涵盖环境配置、串口初始化、数据收发、错误处理等核心功能,并提供了完整的代码示例,帮助开发者快速掌握跨平台串口通信技术,适用于智能农业、工业自动化等物联网场景。

weixin_30369041的博客 597

排序算法3-堆排序与优先队列

首先说明一点,不要被名字所误导,优先队列并不是一种排序饿算法,而是一种数据结构。这个结构与一般的先入先出的队列不同,它每次出队的是优先级最大的元素。当一个指定优先级的元素入队时,能够很快的把它排到队列中。把这两个放在一起,是因为优先队列是用堆排序的方法设计的。 首先先看堆排序吧。堆是一个完全二叉树。完全二叉树我们之前已提过,就是它的前面是满的,直到最后一层除外。最后一层从左边起一直都有叶子,但是

thefutureisour的专栏 4549

SPL06气压温度传感器SPI驱动与补偿算法详解

气压传感器与温度传感器是嵌入式环境感知系统的核心组件,其测量精度高度依赖于MEMS芯片的校准参数与非线性补偿机制。SPL06作为集成式高精度数字传感器,采用24位Σ-Δ ADC与片内补偿引擎,需结合唯一出厂校准系数(即‘芯片指纹’)进行多阶数学修正,才能将原始ADC值转化为符合计量要求的帕斯卡(Pa)与摄氏度(℃)物理量。该过程涵盖SPI通信协议解析、寄存器时序控制、大端数据拼接、二进制补码处理及浮点/定点混合运算等典型嵌入式工程实践。广泛应用于无人机高度计、智能穿戴海拔监测与IoT气象终端中。

weixin_34640289的博客 143

芒果YOLO11改进146:OBB旋转检测头Head篇:即插即用|轻量化非对称多级压缩LOADH旋转检测头,原创改进适配YOLOv8高效检测头,检测头新颖改进,全网首发独一份

OBB旋转检测头Head篇:即插即用|轻量化非对称多级压缩LOADH旋转检测头,原创改进适配YOLOv8高效检测头,检测头新颖改进,全网首发独一份

包括YOLOv5、YOLOv7、YOLOv8等模型改进 645

GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...

本篇文章关键字:优先队列排序算法、小顶堆、大顶堆 背景 接着 https://mengkang.net/1328.html 的案例,我们继续磕。 回顾下实验3中的例子 select `aid`,sum(`pv`) as num from article_rank force index(idx_aid_day_pv) where `day...

weixin_34378045的博客 85

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

堆排序和优先队列

堆排序 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。首先简单了解下堆结构。 堆 堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。如下图:    同时,我们对堆中的结点按层进行编号,将这种逻辑结构映射到数组中就是下面这个样子 该数组从逻辑上讲就是一个堆结构,我们用简单的公式来描述一下堆的定义就是: 大顶堆:arr[i

m0_49003264的博客 562

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

必学排序算法——堆排序

堆排序算法是必须掌握的一种基础算法,在一些比较出名的竞赛acm、蓝桥杯,并且在一些公司面试题中都可能会出现,而且作为简单题我们必须要拿下,所以我们要引起重视,下面让我们来深入了解堆排序算法。堆排序(Heap Sort)是一种基于堆数据结构的比较排序算法。堆是一个近似完全二叉树的结构,分为最大堆和最小堆。在最大堆中,父节点的值总是大于或等于其子节点的值;而在最小堆中,父节点的值总是小于或等于其子节点的值。堆排序通常使用最大堆来升序排序数组,使用最小堆则可以降序排序数组。

ycs66的博客 3998

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

【算法】堆排序与优先队列——傻瓜式教学

q

Reimia的博客 670

Java 与排序算法(7):堆排序

堆排序是一种基于比较的排序算法,它的基本思想是将待排序的元素构建成一个堆,然后依次将堆顶元素取出,放到已排序的序列中,直到堆中所有元素都被取出,最终得到一个有序的序列。堆是一种特殊的树形数据结构,它满足以下两个条件:堆是一颗完全二叉树。堆中每个节点的值都大于等于(或小于等于)其左右子节点的值,这种性质称为堆的性质。堆排序的基本步骤如下:构建堆:将待排序的元素构建成一个堆,可以使用数组来表示堆,数组中下标为 i 的元素的左子节点下标为 2i+1,右子节点下标为 2i+2。

暗星涌动 2730

[算法系列]优先队列,堆与堆排序

优先队列,堆与堆排序 1 优先队列 有时我们在处理有序元素时,并不一定要求他们全部有序. 很多情况下我们会收集一些元素, 处理当前最大的元素, 然后再收集更多元素, 再处理当前最大元素 … 这种情况下, 一个合适的数据结构一个支持两种操作 : 删除最大元素和 插入元素. 这种数据类型叫做 优先队列. 我们可以使用有序或无序的数组或链表实现.使用无序序列是解决这个问题的 惰性方法, 我们仅在必要的时...

lawfree的博客 3208

优先队列及堆排序

优先队列 定义 许多应用程序要处理许多有序的元素,但不一定要求他们全部有序;或者不要求一次就将他们排序,很多情况下我们会处理当前键值最大的元素,然后再搜集更多的元素,在处理最大的元素,或者为每一个应用分配一个优先级,并总是处理下一个优先级最高的事件。 在这种情况下,一个合适的数据结构应该支持两种操作:删除最大元素、插入元素。这种数据结构叫做优先队列。优先队列的使用和队列及栈类似。通...

weixin_30852451的博客 358

排序算法之堆排序

堆排序(Heapsort)是一种利用堆这种数据结构设计的排序算法。堆是一个近似完全二叉树的结构,并同时满足堆的性质:即子节点的键值或索引总是小于(或大于)它的父节点。堆排序是一种利用堆的概念来排序的选择排序变种。分为两种方法:每个节点的值都大于等于其左右孩子节点的值,称为大顶堆;或者每个节点的值都小于等于其左右孩子节点的值,称为小顶堆。该算法的时间复杂度为。

2401_85373732的博客 374

堆排序:优先队列的应用

堆排序是一种高效的排序算法,掌握它不仅有助于解决相关的算法问题,也能帮助我们更好地理解堆数据结构。希望这篇文章对大家有所帮助,祝大家刷题愉快!本文由 cannonjinx 原创,转载请注明出处。

cannonjinx的博客 4130

排序算法-堆排序与优先队列

01 开门见山 堆排序的时间复杂度是O(n*lgn). 因为堆排序是树形结构. "堆"的数据结构来进行信息管理.不仅用在堆排序中, 而且也可以构造一种有效的优先队列. 02 堆 (二叉)堆是一个数组, 可以看成近似完全的二叉树. 树上的每个结点对应数组中的一个元素. 该树是从左向右填充. 如图: 左边是二叉树的形式,右边是数组的形式, 此为大顶堆. 最大堆 就是父结点大于等于子结点的堆.最大元素是在树的根节点. 最小堆 就是父结点小于等于子结点的堆.最小元素是在树的根节点. 建立最大堆过程 如图: 图a

m0_37759287的博客 293
上一篇: 排序算法(2)—归并排序,快速排序
下一篇: 算法-树(1)—BST(二叉搜索树)
luoz_python
博客等级 码龄10年 57粉丝 47原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值