数据结构 | 利用二叉堆实现优先级队列

news2024/11/28 20:39:10

目录

一、二叉堆的操作

二、二叉堆的实现

2.1 结构属性

2.2 堆的有序性

2.3 堆操作


队列有一个重要的变体,叫作优先级队列。和队列一样,优先级队列从头部移除元素,不过元素的逻辑顺序是由优先级决定的。优先级最高的元素在最前,优先级最低的元素在最后。因此,当一个元素入队时,它可能直接被移到优先级队列的头部。

实现优先级队列的经典方法是使用叫作二叉堆的数据结构。二叉堆的入队操作和出队操作均可达到O(logn)

二叉堆有两个常见的变体:最小堆(最小的元素一直在队首)与最大堆(最大的元素一直在队首)。

本篇文章实现的是最小堆

一、二叉堆的操作

我们将实现以下基本的二叉堆方法。

  • BinaryHeap()新建一个空的二叉堆。
  • insert(k)往堆中加入一个新元素。
  • findMin()返回最小的元素,元素留在堆中。
  • delMin()返回最小的元素,并将该元素从堆中移除。
  • isEmpty()在堆为空时返回True,否则返回False。
  • size()返回堆中元素的个数。
  • buildHeap(list)根据一个列表创建堆。
>>> from pythonds.trees import BinaryHeap
>>> bh=BinaryHeap()
>>> bh.insert(5)
>>> bh.insert(7)
>>> bh.insert(3)
>>> bh.insert(11)
>>> print(bh.delMin())
3
>>> print(bh.delMin())
5
>>> print(bh.delMin())
7
>>> print(bh.delMin())
11

二、二叉堆的实现

2.1 结构属性

为了使二叉树能够高效地工作,我们利用树的对数性质来表示它。为了保证对数性能,必须维持树的平衡。平衡的二叉树是指,其根节点的左右子树含有数量大致相等的节点。在实现二叉堆时,我们通过创建一颗完全二叉树来维持树的平衡。在完全二叉树中,除了最底层,其他每一层的节点都是满的。在最底层,我们从左往右填充节点。

完全二叉树的另一个有趣之处在于,可以用一个列表来表示它,而不需要采用“列表之列表”或“节点与引用”表示法。由于树是完全的,因此,因此对于在列表中处于位置p的节点来说,它的左子节点正好处于位置2p;同理,右子节点处于位置2p+1。若要找到树中任意节点的父节点,只需使用python的整数除法即可。给定列表中位置n处的节点,其父节点的位置就是n/2。

2.2 堆的有序性

我们用来存储堆元素的方法依赖于堆的有序性。堆的有序性是指:对于堆中任意元素x及其父元素p,p都不大于x。

2.3 堆操作

新建二叉堆:

def __init__(self):
    self.heapList=[0]
    self.currentSize=0

接下来实现insert方法。将元素加入列表的最简单、最高效的方法就是将元素追加到列表的末尾。追加操作的优点在于,它能保证完全数的性质,但缺点是很可能会破坏堆的结构性质。不过可以写一个方法,通过比较新元素与其父元素来重新获得堆的结构性质。如果新元素小于其父元素,就将二者交换。

perUp方法:

def perUp(self,i):
    while i//2>0:
        if self.heapList[i]<self.heapList[i//2]:
            tmp=self.heapList[i//2]
            self.heapList[i//2]=self.heapList[i]
            self.heapList[i]=tmp
        i=i//2

向二叉堆中新加元素:

def insert(self,k):
    self.heapList.append(k)
    self.currentSize=self.currentSize+1
    self.perUp(self.currentSize)

正确定义insert方法后,就可以编写delMin方法。既然堆的结构性质要求根节点是树的最小元素,那么查找最小值就很简单。delMin方法的难点在于,如果在移除根节点之后重获堆的结构性质和有序性。可以分两步重建堆。第一步,取出列表中的最后一个元素,将其移到根节点的位置。移动最后一个元素保证了堆的结构性质,但可能破坏二叉堆的有序性。第二步,将新的根节点沿着树推到正确的位置,以重获堆的有序性。

perDown方法和minChild方法:

def percDown(self,i):
    while (i*2)<=self.currentSize:
        mc=self.minChild(i)
        if self.heapList[i]>self.heapList[mc]:
            tmp=self.heapList[i]
            self.heapList[i]=self.heapList[mc]
            self.heapList[mc]=tmp
        i=mc

def minChild(self,i):
    if i*2+1>self.currentSize:
        return i*2
    else:
        if self.heapList[i*2]<self.heapList[i*2+1]:
            return i*2
        else:
            return i*2+1

从二叉堆中删除最小的元素:

def delMin(self):
    retval=self.heapList[1]
    self.heapList[1]=self.heapList[self.currentSize]
    self.currentSize=self.currentSize-1
    self.heapList.pop()
    self.percDown(1)
    return retval

根据元素列表构建堆:

def bulidHeap(self,alist):
    i=len(alist)//2
    self.currentSize=len(alist)
    self.heapList=[0]+alist[:]
    while (i>0):
        self.percDown(i)
        i=i-1

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

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

相关文章

【程序环境与预处理玩转指南】

本章重点&#xff1a; 程序的翻译环境 程序的执行环境 详解&#xff1a;C语言程序的编译链接 预定义符号介绍 预处理指令 #define 宏和函数的对比 预处理操作符#和##的介绍 命令定义 预处理指令 #include 预处理指令 #undef 条件编译 1. 程序的翻译环境和执行环境 在…

Java基础入门篇——IntelliJ IDEA下载与安装(四)

IntelliJ IDEA是一款流行的Java集成开发环境&#xff08;IDE&#xff09;&#xff0c;由JetBrains公司开发。你可以按照以下步骤下载和安装IntelliJ IDEA&#xff1a; 一、下载 访问官方网站&#xff1a;打开浏览器&#xff0c;访问JetBrains的官方网站。你可以直接在搜索引擎…

SAP MM学习笔记15-物料调达中的Master数据(2)-品目Master

SAP中做一个购买发注的时候&#xff0c;涉及到以下Master数据&#xff1a; 1&#xff0c;仕入先Master&#xff08;供应商&#xff09;&#xff1a;跟谁买 2&#xff0c;品目Master&#xff08;物料&#xff09;&#xff1a;买什么 3&#xff0c;购买情报&#xff1a;什么价…

MONGODB ---- Austindatabases 历年文章合集

开头还是介绍一下群&#xff0c;如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;在新加的朋友会分到2群&#xff08;共…

过滤器和拦截器的六大区别

平时觉得简单的知识点&#xff0c;但通常都不会太关注细节&#xff0c;一旦被别人问起来&#xff0c;反倒说不出个所以然来。真的就是一看就会一说就废。下面带大家一起结合实践来区分过滤器和拦截器吧~ 通俗理解&#xff1a; &#xff08;1&#xff09;过滤器&#xff08;Fil…

CMake 3.13.4 or higher is required. You are running version 3.10.2

ubuntu 安装 cmake&#xff0c;但是apt安装的版本太低&#xff0c;需要其他安装方法。 参考视频 https://www.youtube.com/watch?v_yFPO1ofyF0 以下是对视频内容的提炼&#xff0c;就两点 1、下载需要版本的sh文件&#xff1b;2、安装 一、下载需要版本的sh文件 https://cma…

【ArcGIS Pro二次开发】(58):数据的本地化存储

在做村规工具的过程中&#xff0c;需要设置一些参数&#xff0c;比如说导图的DPI&#xff0c;需要导出的图名等等。 每次导图前都需要设置参数&#xff0c;虽然有默认值&#xff0c;但还是需要不时的修改。 在使用的过程中&#xff0c;可能会有一些常用的参数&#xff0c;希望…

shell 入门练习小记

一、hello world #!/bin/bash echo "Hello World !"#! 为约定的标记&#xff0c;告诉系统这个脚本需要什么解释器执行&#xff0c;后接绝对路径 /bin/bash 表示期望 bash去解析并运行shell echo用于向窗口输出文本 chmod x ./test.sh #给脚本赋执行权限 ./test.sh …

Leetcode-每日一题【剑指 Offer 10- II. 青蛙跳台阶问题】

题目 一只青蛙一次可以跳上1级台阶&#xff0c;也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 答案需要取模 1e97&#xff08;1000000007&#xff09;&#xff0c;如计算初始结果为&#xff1a;1000000008&#xff0c;请返回 1。 示例 1&#xff1a; 输…

Linux命令200例:tr用于对输入的文本进行字符转换、删除、替换等

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &…

龙架构 Arch Linux 发行版发布

导读近日&#xff0c;龙架构 Arch Linux 发行版官方网站宣布结束 beta 状态&#xff0c;正式支持龙架构 (LoongArch)。 Arch Linux 是一种轻量级、可定制、灵活的 Linux 操作系统。作为一款简单、现代、开放的操作系统&#xff0c;Arch Linux 旨在基于 “KISS 原则”&#xff0…

2020年12月 Python(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

一、单选题 第1题 执行语句print(1010.0)的结果为&#xff1f; A&#xff1a;10 B&#xff1a;10.0 C&#xff1a;True D&#xff1a;False 正确的答案是 C&#xff1a;True。 解析&#xff1a;在Python中&#xff0c;比较运算符 “” 用于比较两个值是否相等。在这个特…

解释器模式(Interpreter)

解释器模式是一种行为设计模式&#xff0c;可以解释语言的语法或表达式。给定一个语言&#xff0c;定义它的文法的一种表示&#xff0c;然后定义一个解释器&#xff0c;使用该文法来解释语言中的句子。解释器模式提供了评估语言的语法或表达式的方式。 Interpreter is a behav…

以太网ICMP协议(九)

目录 一、概述 二、ICMP消息类型 2.1 ICMP类型0和类型8&#xff1a;Ping功能 2.2 ICMP类型3&#xff1a;目标不可达 2.3 ICMP类型5&#xff1a;重定向 2.4 ICMP类型11&#xff1a;超时 三、报文格式 一、概述 由于IP协议是不可靠的通信协议&#xff0c;需要有其他协议的…

线程池的使用案例一

一、配置线程池 1、不推荐的方式 ExecutorService executorService Executors.newFixedThreadPool(); // 创建⼀个固定⼤⼩的线程池&#xff0c;可控制并发的线程数&#xff0c;超出的线程会在队列中等待&#xff1b; ExecutorService executorService Executors.newCache…

无监督SLAM框架

因为之前做过双目立体匹配相关项目&#xff0c;当时就了解到有一些无监督方法。最近涉及到SLAM相关项目&#xff0c;想到理论上可以用photo loss无监督学习光流和pose&#xff0c;因此查看了有没有SLAM无监督的相关论文。发现确实有几篇论文。但总感觉设计的不是很好&#xff0…

【计算机视觉|风格迁移】PP-GAN:使用GAN的地标提取器将韩国人像的风格转化为身份证照片

本系列博文为深度学习/计算机视觉论文笔记&#xff0c;转载请注明出处 标题&#xff1a;PP-GAN : Style Transfer from Korean Portraits to ID Photos Using Landmark Extractor with GAN 链接&#xff1a;[2306.13418] PP-GAN : Style Transfer from Korean Portraits to ID…

单元测试、接口测试、功能测试的区别

单元测试、接口测试、功能测试的区别 自动化测试分为单元自动化测试、接口自动化测试和功能自动化测试 功能测试的进行&#xff1a;首先编写测试用例&#xff0c;测试用例中最主要的是测试步骤和预期结果&#xff1b;测试人员根据测试用例执行操作步骤&#xff0c;然后通过眼睛…

想知道程序员工资最高的城市吗?来看看这10个城市排名吧

大家好&#xff0c;这里是程序员晚枫。 在下班回家的路上&#xff0c;又和同事聊起重庆工资不高的问题&#xff0c;那么国内哪些城市程序员工资最高呢&#xff1f;今天我们一起来看一下&#xff1a;我国程序员工资最高的前10个城市。 以下是我国程序员工资最高的前10个城市&a…

使用 POI 在 Word 中重新开始编号、自定义标题格式

效果图 引入依赖 <!-- https://mvnrepository.com/artifact/org.apache.poi/poi --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency><!-- https…