Python heap

article/2025/10/25 16:10:28

原文:https://blog.csdn.net/dta0502/article/details/80834787 

堆是一类特殊的树,堆的通用特点就是父节点会大于或小于所有子节点(儿子不分左右)。一个最小堆(min-heap)就是其中的每一个节点都小于或等于其两个子节点的一个二叉树。一个最大堆(max-heap)将最大的节点放置到最靠近根节点的位置。

注意:不能把这种类型的堆和计算机用于管理动态内存的堆搞混了。下面是区别:

数据结构中:栈是一种具有后进先出的数据结构,堆是一种经过排序的树形数据结构,每个节点都有一个值。通常我们所说的堆的数据结构是指二叉树。堆的特点是根节点的值最小(或最大),且根节点的两个树也是一个堆。由于堆的这个特性,常用来实现优先队列。

内存分配中:栈是系统自动分配空间的,堆则是程序员根据需要自己申请的空间。由于栈上的空间是自动分配自动回收的,所以栈上的数据的生存周期只是在函数的运行过程中,运行后就释放掉,不可以再访问。而堆上的数据只要程序员不释放空间,就一直可以访问到,不过缺点是一旦忘记释放会造成内存泄露。使用栈就像我们去饭馆里吃饭,只管点菜(发出申请)、付钱、吃(使用),吃饱了就走,不必理会切菜,洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处就是快捷,但是自由度小。使用堆就像是自己动手做喜欢的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

堆接口
我们将使用堆来实现一个优先队列,堆接口应该包含返回其大小、添加项、删除项和查看项的方法。

堆接口中的方法
方法    作用

  • heap.isEmpty()    如果堆为空,返回True,否则,返回False
  • heap.__len__()    等同于len(heap),返回堆中项的数目
  • heap.__iter__()    等同于iter(heap)或for item in heap;从最小到最大地访问各项
  • heap.__str__()    等同于str(heap),返回一个字符串,表示堆的形状
  • heap.__contains__(item)    等同于item in heap。如果item在堆中,返回True
  • heap.__add__(otherHeap)    等同于heap + otherHeap,返回一个新的堆,其内容是heap和otherHeap的内容
  • heap.__eq__(anyObject)    等同于heap == otherObject,如果堆等于anyObject的话,返回True。如果两个堆包含相同的项,那么它们相等
  • heap.peek()    返回heap最顶部的项。先验条件:heap不为空
  • heap.add(item)    将item插入到其在heap中适当的位置
  • heap.pop()    返回heap最顶部的项。先验条件:heap不为空

两个最为重要的堆操作是add和pop。add方法接收一个可比较的元素作为参数,并且将该元素插入到堆中合适的位置。这个位置通常位于一个比它大的元素之上的一层,并且位于一个比它小的元素之下。重复的元素会放置在之前输入的那个元素之下。pop方法删除堆中最顶端的元素,并返回最顶端的元素,并且维护堆的属性。peek操作返回堆最顶端的元素,但是不会删除它。

add方法(插入)和pop方法(删除)在整个堆实现都会使用,它们定义于ArrayHeap类中。在基于数组的实现中,这两个方法都需要在数组中维护堆的结构(实际上,使用了一个Python列表,但是在如下的讨论中,我们将这个结构称为一个数组)。

堆的实现
插入操作add
目标是在堆中找到新元素的合适位置,并且将其插入。下面是插入的策略:

(1)首先在堆的底部插入该元素,在数组实现中,这是数组中当前最后一个元素之后的位置

(2)然后,进入一个循环,只要新元素的值小于其父节点的值,循环就让这个新元素沿着堆向上“走”,将新的元素和其父节点交换。当这个过程停止的时候(要么新的元素大于或等于其父节点,要么到达了顶部的节点),新的元素就位于其适当的位置。

注意:数组一个元素的父节点的位置是通过将元素的位置减去1并且将结果除以2计算得到的。堆的最顶端在数组中的位置是0。

   

 def add(self, item):self._size += 1self._heap.append(item)curPos = len(self._heap) - 1while curPos > 0:parent = (curPos - 1) // 2parentItem = self._heap[parent]if parentItem <= item:breakelse:self._heap[curPos] = self._heap[parent]self._heap[parent] = itemcurPos = parent


该方法的快速分析揭示了,你最多需要进行log2N次比较,就可以从底部移动至树的上面,因此,一次add操作是O(logN)。该方法偶尔会触发底层数组的大小翻倍,当发生翻倍的情况时,该操作就是O(n),但这是将所有的相加操作都累计到一起,而每次相加操作都是O(1)。

删除操作pop
删除的目标是在删除根节点之后,返回该节点中的元素,并且调整其他节点的位置以维护堆属性。下面是删除操作的策略:

(1)首先,保存堆中的顶部元素和底部元素的指针,并且将该元素从堆的底部移动到顶部

(2)从堆的顶部往下走,将最小的元素向上移动一层,直到到达堆的底部

   

 def pop(self):if self.isEmpty():raise Exception("Heap is empty")self._size -= 1topItem = self._heap[0]bottomItem = self._heap.pop(len(self._heap) - 1)if len(self._heap) == 0:return bottomItemself._heap[0] = bottomItemlastIndex = len(self._heap) - 1curPos = 0while True:leftChild = 2 * curPos + 1 rightChild = 2 * curPos + 2if leftChild > lastIndex:breakif rightChild > lastIndex:maxChild = leftChild;else:leftItem  = self._heap[leftChild]rightItem = self._heap[rightChild]if leftItem < rightItem:maxChild = leftChildelse:maxChild = rightChildmaxItem = self._heap[maxChild]if bottomItem <= maxItem:breakelse:self._heap[curPos] = self._heap[maxChild]self._heap[maxChild] = bottomItemcurPos = maxChildreturn topItem
分析显示了删除所需的比较次数最多为log2N,因此pop操作为O(logN)。

本文是数据结构(用Python实现)这本书的读书笔记!
--------------------- 
作者:dta0502 
来源:CSDN 
原文:https://blog.csdn.net/dta0502/article/details/80834787 
版权声明:本文为博主原创文章,转载请附上博文链接!


http://chatgpt.dhexx.cn/article/htqIXDwm.shtml

相关文章

Stack and Heap

JVM 分配内存进入以下区域 1&#xff1a; Heap 2&#xff1a;Stack 3&#xff1a;Code 4&#xff1a;Static jvm有效的管理分配到这几个内存区域。 Code section 代码区 包含这个 字节码文件 (byte code) Stack section (栈区域) 包含 方法&#xff08;methods&a…

堆-heap

priority queue可以借用堆&#xff08;heap&#xff09;,binary heap是一种complete binary tree(完全二叉树&#xff09; 完全二叉树&#xff1a;binary tree除最底层叶节点之外&#xff0c;是填满&#xff0c;最底层叶节点由左到右不得有空隙。 用vector来存储所有节点&…

Kubernetes安装系列之heapster安装

虽然heapster已经即将退休&#xff0c;为了纪念一下&#xff0c;这篇文章整理一下heapstergrafanaInfluxdb组合对于kubernetes的node与资源进行监控的插件安装与设定方法&#xff0c;本文以脚本的方式进行固化&#xff0c;内容仍然放在github的easypack上。 整体操作 https:/…

Heapster -- Kubernetes Dashboard集成Heapster

原始kubernetes dashboard的界面中仅显示了pod一些配置信息&#xff0c;无法图形化展现集群度量指标信息。原始图如下&#xff08;此处从网上找了一个图..&#xff09;&#xff1a; 而如果要展示图形化的集群度量指标信息&#xff0c;就需要安装一个dashboard插件&#xff1a;h…

HeapSort

堆的定义&#xff1a; n个关键字序列K[1....n]称为堆&#xff0c;当且仅当改序列满足&#xff1a; 第一种为&#xff1a;小根堆&#xff1a;每个结点的值都小于或等于左右孩子结点 第二种为&#xff1a;大根堆&#xff1a;每个结点的值都大于或等于左右孩子结点 堆是一种完全二…

heap.h

上一篇写了写链表&#xff0c;这篇写下堆&#xff0c;这个结构接触的不多&#xff0c;所以正好学习一下libhv中的堆&#xff0c;这个堆的实现比较灵活&#xff0c;即可以是大顶堆也可以是小顶堆&#xff0c;通过比较函数是比大还是比小来区别&#xff0c;当然&#xff0c;如果没…

部署 heapster 插件

说明&#xff1a;本部署文章参照了 https://github.com/opsnull/follow-me-install-kubernetes-cluster &#xff0c;欢迎给作者star Heapster是一个收集者&#xff0c;将每个Node上的cAdvisor的数据进行汇总&#xff0c;然后导到第三方工具(如InfluxDB)。 Heapster 是通过调用…

每天5分钟玩转Kubernetes | Heapster

书籍来源&#xff1a;cloudman《每天5分钟玩转Kubernetes》 一边学习一边整理老师的课程内容及试验笔记&#xff0c;并与大家分享&#xff0c;侵权即删&#xff0c;谢谢支持&#xff01; 附上汇总贴&#xff1a;每天5分钟玩转Kubernetes | 汇总_COCOgsta的博客-CSDN博客 Heap…

Kubernetes监控Heapster介绍

什么是Heapster&#xff1f; Heapster是容器集群监控和性能分析工具&#xff0c;天然的支持Kubernetes和CoreOS。 Kubernetes有个出名的监控agent—cAdvisor。在每个kubernetes Node上都会运行cAdvisor&#xff0c;它会收集本机以及容器的监控数据(cpu,memory,filesystem,netw…

nginx部署https域名

目录 一、准备工作 二、部署项目 三、修改nginx的配置文件 一、准备工作 1、首先你要有一台服务器&#xff0c;本篇文章是创建在腾讯云服务器的基础上的&#xff0c;仅供参考 2、在服务器上注册域名&#xff0c;这个域名注册等待审核时间较长&#xff0c;建议提早注册&…

域名解析与nginx配置

dns解析 阿里云服务器dns域名解析配置&#xff0c;记录值就是阿里云服务器的ip nginx配置 远程到阿里云服务器上对nginx进行配置&#xff1a; nginx反向代理配置&#xff1a; 修改配置后&#xff0c;重启nginx服务 进入目录&#xff1a;cd /usr/sbin 强制杀死进程&#xff…

linux nginx部署项目配置域名

一.把项目打包&#xff08;jar&#xff09; 二.把jar包通过xshell上传 三.编辑nginx.conf文件&#xff0c;配置域名&#xff0c;每配置一个域名就复制一份里面的server 1 代表你所要配置的域名 2 代表你项目浏览器访问路径 四.在项目上传的目录下&#xff08;jar包所放的位…

Docker部署nginx、配置域名

文章目录 背景1. 拉取nginx镜像2. 启动nginx3. 通过docker修改nginx配置1) 挂载配置文件2) 重新加载配置文件 4. 配置我的域名小结 背景 docker 容器相关技术已经成为了现在开发和运维人员的热门技术之一&#xff0c;docker就像一个集装箱能够将各种应用放入到集装箱里的盒子里…

nginx配置域名访问/禁止ip访问

一 背景 为什么要禁止ip访问? 为了避免其他人把未备案的域名解析到自己的服务器IP&#xff0c;而导致服务器被断网&#xff0c;我们可以通过禁止使用ip访问的方法&#xff0c;防止此类事情的发生。 二 解决方法 修改配置文件nginx.conf, 其中2.2的方法可以参考 ubuntu18.04…

配置nginx域名转发

这应该是&#xff0c;我在这个网站的最后一篇博客了。 国庆的时候不知道为什么突然买了个服务器&#xff0c;我打算自己建一个博客网站了&#xff0c;然后前两天域名刚备案成功&#xff0c;晚上有空就配置服务器。 服务器先安装jdk&#xff0c;jre基础环境&#xff0c;然后ngi…

Nginx 服务器配置域名证书

1、首先去申请域名证书&#xff0c;或者购买。都可以&#xff0c;腾讯、阿里、华为、均可&#xff0c;最好域名跟证书在一个服务商处。 2、申请好域名后&#xff0c;进行域名解析配置。证书方会让你&#xff0c;添加提供的解析内容。 3、下载证书&#xff0c;证书提供商会提供…

【Nginx】Nginx主机域名配置

一、配置多个端口访问不同文件 相同域名&#xff0c;不同端口&#xff0c;不同文件 #两个不同文件夹&#xff0c;分别存放不同文件 [rootnginx ~]# mkdir /www/work_01 -p [rootnginx ~]# mkdir /www/work_02 [rootnginx ~]# vim /www/work_01/index.html this is work_01! [r…

阿里云ECS部署Nginx配置域名访问

目录 前言环境 具体步骤服务器域名SSL证书Nginx配置 前言 记录下阿里云服务器建站的过程&#xff08;回回建&#xff0c;回回忘&#xff0c;尴尬。。。&#xff09; 环境 ECS&#xff08;Centos7.6&#xff09; Nginx 具体步骤 服务器 首先&#xff0c;需要购买一台服务器 …

Nginx配置域名服务小试牛刀

最近实际操作的一个项目哦&#xff0c;大家看下有没有帮助哦&#xff01;Nginx 配置通过域名访问项目&#xff01; 项目目的&#xff1a;将打包好的项目jar文件部署起来&#xff0c;并能够通过域名访问 准备条件&#xff1a; 1.服务器端安装需要的1.jdk 选择1.8版本 Linux…

nginx 配置域名映射到本地IP

需求背景 项目需求需要在不同的域名下&#xff0c;判断展示不同的内容&#xff0c;为了模拟线上的正式域名&#xff0c;有以下几种方案&#xff1a; 方案一&#xff1a; 配置host: 1、找到host的文件地址&#xff08;不会的百度&#xff09; 2、配置host: 127.0.0.1 www.t…