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

python不调用heapq库 实现大顶堆,小顶堆

参考了博客,并对其进行了堆的push() 和 降序排序的补充

【精选】图解堆排序及其Python实现_python 实现小顶堆-CSDN博客

目录

大顶堆

调用结果展示:

小顶堆:

调用结果展示:

此结果与调用heapq库中的heapify(arr)函数等效

其中定义的push()函数与heapy库中的heappush(arr,num)函数等效

大顶堆

import copy
# 导入copy 后面用到深拷贝 为排序不改变原值考虑class Heap(object):"""实现大顶堆及堆排序"""def __init__(self, arr: list):"""arr: 用户输入的待排序数组"""self.arr = arrself.len = len(arr)# self.sorted1_arr = []self.sorted2_arr = []# 一旦创建类即自动转为大顶堆数组self.create_heap()def heapify(self, parent_index):"""维护堆的性质"""# 假设当前父节点是子树中最大的值下标largest = parent_index# 左右孩子节点下标,有可能不存在left_child_index = parent_index * 2 + 1right_child_index = parent_index * 2 + 2# 判断左右子节点是否存在,并找出其中最大的值下标if left_child_index < self.len and self.arr[largest] < self.arr[left_child_index]:largest = left_child_indexif right_child_index < self.len and self.arr[largest] < self.arr[right_child_index]:largest = right_child_index# 需要进行位置调整,并进行递归调整if not (largest == parent_index):self.arr[parent_index], self.arr[largest] = self.arr[largest], self.arr[parent_index]self.heapify(largest)def create_heap(self):"""初始化堆"""last_parent_index = (self.len - 1) // 2  # 最后一个包含子节点的父节点下标for i in range(last_parent_index, -1 , -1):self.heapify(i)def pop(self):peak = self.arr[0]# 交换堆顶与最后一个元素,然后重新建堆self.arr[0] = self.arr[-1]self.arr.pop(-1)self.len -= 1self.heapify(0)  # 从上到下维护堆return peak# 在某人博客基础上加了增加元素的def push(self,elem):self.arr.append(elem)self.len += 1 # 记录加入元素的下标及父节点下标tmp = self.len - 1parent_note = (tmp-1) // 2# 在所加入的那一条链上 不断比较与父节点的大小 并交换while parent_note>=0 and self.arr[parent_note] < self.arr[tmp]:self.arr[parent_note], self.arr[tmp] = self.arr[tmp], self.arr[parent_note]# 更新加入节点和父节点的下标tmp = parent_noteparent_note = (parent_note-1) // 2def heap_sort1(self):"""堆排序,输出排序后的数组,升序"""self.arr2 = copy.deepcopy(self.arr)self.sorted1_arr = [0] * len(self.arr)for i in range(len(self.arr)-1,-1,-1):self.sorted1_arr[i] = self.pop()self.arr = self.arr2return self.sorted1_arrdef heap_sort2(self):"""堆排序,输出排序后的数组,降序"""self.arr2 = copy.deepcopy(self.arr)for i in range(len(self.arr)):self.sorted2_arr.append(self.pop())self.arr = self.arr2return self.sorted2_arr

调用结果展示:

h = Heap([18, 34, 26, 25, 30, 8, 28, 13])
print(h.arr)
print(h.pop())
h.push(36)
print(h.arr)
print(h.heap_sort2())
print(h.heap_sort1())#结果展示
[34, 30, 28, 25, 18, 8, 26, 13]
34
[36, 25, 30, 13, 18, 8, 26, 28]
[36, 30, 28, 26, 25, 18, 13, 8]
[25, 30, 13, 18, 8, 26, 28, 36]

小顶堆:

搞懂大顶堆 小顶堆很快秒 只需改几个符号

import copy
# 导入copy 后面用到深拷贝 为排序不改变原值考虑class Heap(object):"""实现小顶堆及堆排序"""def __init__(self, arr: list):"""arr: 用户输入的待排序数组"""self.arr = arrself.len = len(arr)# self.sorted1_arr = []self.sorted2_arr = []# 一旦创建类即自动转为大顶堆数组self.create_heap()def heapify(self, parent_index):"""维护堆的性质"""# 假设当前父节点是子树中最小的值下标largest = parent_index# 左右孩子节点下标,有可能不存在left_child_index = parent_index * 2 + 1right_child_index = parent_index * 2 + 2# 判断左右子节点是否存在,并找出其中最小的值下标if left_child_index < self.len and self.arr[largest] > self.arr[left_child_index]:largest = left_child_indexif right_child_index < self.len and self.arr[largest] > self.arr[right_child_index]:largest = right_child_index# 需要进行位置调整,并进行递归调整if not (largest == parent_index):self.arr[parent_index], self.arr[largest] = self.arr[largest], self.arr[parent_index]self.heapify(largest)def create_heap(self):"""初始化堆"""last_parent_index = (self.len - 1) // 2  # 最后一个包含子节点的父节点下标for i in range(last_parent_index, -1 , -1):self.heapify(i)def pop(self):peak = self.arr[0]# 交换堆顶与最后一个元素,然后重新建堆self.arr[0] = self.arr[-1]self.arr.pop(-1)self.len -= 1self.heapify(0)  # 从上到下维护堆return peak# 在某人博客基础上加了增加元素的def push(self,elem):self.arr.append(elem)self.len += 1 # 记录加入元素的下标及父节点下标tmp = self.len - 1parent_note = (tmp-1) // 2# 在所加入的那一条链上 不断比较与父节点的大小 并交换while parent_note>=0 and self.arr[parent_note] > self.arr[tmp]:self.arr[parent_note], self.arr[tmp] = self.arr[tmp], self.arr[parent_note]# 更新加入节点和父节点的下标tmp = parent_noteparent_note = (parent_note-1) // 2def heap_sort1(self):"""堆排序,输出排序后的数组,降序"""self.arr2 = copy.deepcopy(self.arr)self.sorted1_arr = [0] * len(self.arr)for i in range(len(self.arr)-1,-1,-1):self.sorted1_arr[i] = self.pop()self.arr = self.arr2return self.sorted1_arrdef heap_sort2(self):"""堆排序,输出排序后的数组,升序"""self.arr2 = copy.deepcopy(self.arr)for i in range(len(self.arr)):self.sorted2_arr.append(self.pop())self.arr = self.arr2return self.sorted2_arr

调用结果展示:

h = Heap([18, 34, 26, 25, 30, 8, 28, 13])
print(h.arr)
print(h.pop())
h.push(36)
print(h.arr)
print(h.heap_sort2())
print(h.heap_sort1())#结果展示
[8, 13, 18, 25, 30, 26, 28, 34]
8
[13, 25, 18, 34, 30, 26, 28, 36]
[13, 18, 25, 26, 28, 30, 34, 36]
[25, 18, 34, 30, 26, 28, 36, 13]

基于python中的此库只能实现小顶堆

此结果与调用heapq库中的heapify(arr)函数等效

import heapqarr = [18, 34, 26, 25, 30, 8, 28, 13]
heapq.heapify(arr)
print(arr)#结果
[8, 13, 18, 25, 30, 26, 28, 34]

其中定义的push()函数与heapy库中的heappush(arr,num)函数等效

将上述push()函数单独拿出来 就可以模拟heappush()功能

def push(arr,elem):arr.append(elem)n = len(arr)# 记录加入元素的下标及父节点下标tmp = n - 1parent_note = (tmp-1) // 2# 在所加入的那一条链上 不断比较与父节点的大小 并交换while parent_note>=0 and arr[parent_note] > arr[tmp]:arr[parent_note], arr[tmp] = arr[tmp], arr[parent_note]# 更新加入节点和父节点的下标tmp = parent_noteparent_note = (parent_note-1) // 2arr = [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21]
arr1 = []
for item in arr:push(arr1,item)
print(arr1)#结果
[5, 7, 21, 15, 10, 24, 27, 45, 17, 30, 36, 50]

heappush(arr,num)的效果,可见效果一致!

import heapqarray = [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21]
heapq.heapify(array)#结果
[5, 7, 21, 15, 10, 24, 27, 45, 17, 30, 36, 50]

相关文章:

python不调用heapq库 实现大顶堆,小顶堆

参考了博客&#xff0c;并对其进行了堆的push() 和 降序排序的补充 【精选】图解堆排序及其Python实现_python 实现小顶堆-CSDN博客 目录 大顶堆 调用结果展示&#xff1a; 小顶堆&#xff1a; 调用结果展示&#xff1a; 此结果与调用heapq库中的heapify(arr)函数等效 …...

STM32F4X SDIO(二) SDIO协议

上一节简单介绍了SD卡的分类&#xff0c;本节将会介绍SD卡的通信协议&#xff0c;也就是SDIO协议。 STM32F4X SDIO&#xff08;二&#xff09;SDIO协议 SD 卡管脚和寄存器SD卡管脚分布SD卡通信协议SD卡寄存器SD卡内部结构 SDIO总线SDIO总线拓扑SDIO总线协议SDIO协议的基本结构…...

设计模式--7个原则

单一职责原则&#xff1a;一个类负责一项职责。 里氏替换原则&#xff1a;继承与派生的规则。 依赖倒置原则&#xff1a;高层模块不应该依赖基层模块&#xff0c;二者都应该依赖其抽象&#xff1b;抽象不应该依赖细节&#xff1b;细节应该依赖抽象。即针对接口编程&#xff0…...

AltiumDesigner原理图编译错误报告信息解释

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、ViolationsAssociated with Buses 有关总线电⽓错误的各类型&#xff08;共 12 项&#xff09;二、ViolationsAssociated Components 有关元件符号电⽓错误…...

使用 Visual Studio Code 编写 TypeScript程序

安装 TypeScript 首先&#xff0c;确保你已经安装了 TypeScript&#xff0c;如果没有安装&#xff0c;请参考https://blog.csdn.net/David_house/article/details/134077973?spm1001.2014.3001.5502进行安装 创建 新建一个文件夹&#xff0c;用vs code打开&#xff0c;在文…...

科大讯飞发布讯飞星火 3.0;开源AI的现状

&#x1f680; 科大讯飞发布讯飞星火 3.0&#xff0c;综合能力超越ChatGPT&#xff08;非GPT-4版&#xff09; 摘要&#xff1a;科大讯飞在2023全球1024开发者节上宣布讯飞星火 3.0正式发布&#xff0c;号称综合能力已超越ChatGPT。据介绍&#xff0c;星火认知大模型 V3.0在文…...

公网远程访问macOS本地web服务器

# 公网访问macOS本地web服务器【内网穿透】 文章目录 1. 启动Apache服务器2. 公网访问本地web服务2.1 本地安装配置cpolar2.2 创建隧道2.3 测试访问公网地址3. 配置固定二级子域名3.1 保留一个二级子域名3.2 配置二级子域名4. 测试访问公网固定二级子域名 以macOS自带的Apache…...

windows 安装小乌龟

这是什么 这里简单描述一下在windows上如何安装GIT代码管理工具和使用小乌龟版本来调用GIT&#xff0c;并且配置一下git相关信息&#xff0c;可以使用小乌龟来操作代码。也有一些常规git使用方法。 需要的资源 Git-2.42.0-64-bit.exe&#xff08;这个是git代码管理工具&…...

toon boom harmony基础

以下都是tbh快捷键使用&#xff0c;或者一些常用功能介绍 1、在节点视图中&#xff0c;按回车可直接弹出节点库搜索框 2、中心线编辑器 只能编辑用笔刷画出来的线条&#xff0c;铅笔画出来的线条无法编辑。 3、镜头标记 1 右键箭头方向&#xff0c;可弹出下拉&#xff0c;&am…...

JPA联合主键

​ 在实际工作中&#xff0c;我们会经常遇到联合主键的情况&#xff0c;所以我用简单例子列举JPA两种实现联合主键的方式。 1、如何通过IdClass 实现联合主键 第一步:新建一个UserInfoID类&#xff0c;里面是联合主键 Data Builder NoArgsConstructor AllArgsConstructor pu…...

水性杨花:揭秘CSS响应式界面设计,让内容灵活自如,犹如水之变幻

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 ⭐ 专栏简介 &#x1f4d8; 文章引言 一、是…...

fio performance test

fio参数解释 可以使用fio -help查看每个参数&#xff0c;具体的参数左右可以在官网查看how to文档&#xff0c;如下为几个常见的参数描述 filename/dev/emcpowerb 支持文件系统或者裸设备&#xff0c;-filename/dev/sda2或-filename/dev/sdb 或 -filename/dev/nvme0n1direct…...

DevOps持续集成-Jenkins(1)

文章目录 DevOpsDevOps概述Code阶段工具&#xff08;centos7-gitlab主机&#xff09;Windows下安装Git&#xff08;作用是&#xff1a;使我们可以上传代码到GitLab&#xff09;Linux下安装GitLab⭐&#xff08;作用是&#xff1a;运行一个GitLab接收代码&#xff09;环境准备先…...

Pytorch代码入门学习之分类任务(二):定义数据集

一、导包 import torch import torchvision import torchvision.transforms as transforms 二、下载数据集 2.1 代码展示 # 定义数据加载进来后的初始化操作&#xff1a; transform transforms.Compose([# 张量转换&#xff1a;transforms.ToTensor(),# 归一化操作&#x…...

oracle 里常用的一些 create insert update table

1、获得数据库里某个指定的库 SELECT COUNT(*) FROM ALL_TABLES ut WHERE ut.OWNERTJFX AND ut.TABLE_NAME CUR_TIME_BILL; 2、创建一个表&#xff0c;里面的数据可以从一个已存在的表里转移过来 CREATE TABLE temptable AS SELECT * FROM old_tbName //使用现有的表创建一…...

从Mysql架构看一条查询sql的执行过程

1. 通信协议 我们的程序或者工具要操作数据库&#xff0c;第一步要做什么事情&#xff1f; 跟数据库建立连接。 首先&#xff0c;MySQL必须要运行一个服务&#xff0c;监听默认的3306端口。在我们开发系统跟第三方对接的时候&#xff0c;必须要弄清楚的有两件事。 第一个就是通…...

Linux系统下DHCP服务安装部署和使用实例详解(蜜罐)

目录 一、概述 二、具体配置如下&#xff1a; 一、概述 DHCP &#xff1a;动态主机设置协议&#xff08;英语&#xff1a;Dynamic Host Configuration Protocol&#xff0c;DHCP&#xff09;是一个局域网的网络协议&#xff0c;使用UDP协议工作&#xff0c;主要有两个用途&…...

模数转换器-ADC基础

文章目录 一、ADC是什么二、ADC处理采样保持量化编码三、ADC采样的重要参数:测量范围:分辨率(Resolution):精度:采样时间:采样率(Sampling Rate):信噪比(Signal-to-Noise Ratio, SNR):转换时间:一、ADC是什么 ADC(Analog-to-Digital Converter):模拟数字转换器…...

Linux:【1】Linux中的文件权限概念和相关命令

Linux&#xff1a;【1】Linux中的文件权限概念和相关命令 1、什么是文件权限&#xff1f;1.1、文件权限的表示方式 2、理解文件权限2.1、用户权限2.2、组权限2.3、其他权限 3、设置文件权限3.1、chmod 命令3.2、权限符号表示法3.3、权限数字表示法 4、查看文件权限4.1、ls 命令…...

JS实用小计

1.如何创建一个数组大小为100&#xff0c;每个值都为0的数组 // 方法一: Array(100).fill(0);// 方法二: // 注: 如果直接使用 map&#xff0c;会出现稀疏数组 Array.from(Array(100), (x) > 0);// 方法二变体: Array.from({ length: 100 }, (x) > 0); 2.如何逆序一个字…...

Cursor/AI 助手用自然语言操作监控与告警

主要用途告警管理&#xff1a;查询活跃告警和历史告警&#xff0c;查看告警规则和订阅目标监控&#xff1a;浏览和搜索被监控的主机&#xff0c;分析目标状态事件响应&#xff1a;创建和管理告警屏蔽规则、通知规则和事件流水线团队协作&#xff1a;查询用户、团队和业务组快速…...

5分钟快速了解回归测试

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、什么是回归测试 &#xff08;Regression Testing&#xff09; 回归测试是一个系统的质量控制过程&#xff0c;用于验证最近对软件的更改或更新是否无意中引入…...

接口隔离原则原理理解

01.前沿简单介绍学习了 SOLID 原则中的单一职责原则、开闭原则和里式替换原则&#xff0c;今天我们学习第四个原则&#xff0c;接口隔离原则。它对应 SOLID 中的英文字母“I”。对于这个原则&#xff0c;最关键就是理解其中“接口”的含义。那针对“接口”&#xff0c;不同的理…...

终极指南:如何彻底卸载Windows中的Microsoft Edge浏览器

终极指南&#xff1a;如何彻底卸载Windows中的Microsoft Edge浏览器 【免费下载链接】EdgeRemover A PowerShell script that correctly uninstalls or reinstalls Microsoft Edge on Windows 10 & 11. 项目地址: https://gitcode.com/gh_mirrors/ed/EdgeRemover Ed…...

ai辅助开发:向快马描述需求,直接生成jdk1.8实现的控制台通讯录项目

最近在尝试用Java开发一个简单的命令行通讯录程序&#xff0c;正好借这个机会体验了一把AI辅助开发的便利。整个过程让我深刻感受到&#xff0c;合理利用工具真的能大幅提升开发效率。下面记录下这个项目的实现思路和关键点&#xff0c;或许对同样想用JDK1.8练手的朋友有帮助。…...

算力基建工程:NVIDIA产业链下的求职机会——什么是CUDA编程,为什么它成为了2026年的“金饭碗”?

在2026年的北美科技求职市场中&#xff0c;AI 行业的红利正在经历一次极其冷酷的“底层沉淀”。当应用层的 AI 产品陷入残酷的同质化红海竞争&#xff0c;且大量依赖 API 调用的传统软件工程师岗位面临饱和风险时&#xff0c;大厂的巨额资金和核心 Headcount 正在疯狂向一个更硬…...

10. 免费GPU资源汇总(二):AutoDL、阿里云免费算力申请与使用

001、系列引言:为什么你需要关注AutoDL与阿里云免费算力? 深夜两点,示波器的波形还在跳,我盯着屏幕里那个诡异的时序毛刺,突然意识到一件事——手头这块老旧的开发板已经跑不动更复杂的模型验证了。同事上周训练一个轻量级YOLO,在自己的笔记本上跑了整整两天,结果因为散…...

OpenModScan:工业总线测试与协议调试的开源解决方案

OpenModScan&#xff1a;工业总线测试与协议调试的开源解决方案 【免费下载链接】OpenModScan Open ModScan is a Free Modbus Master (Client) Utility 项目地址: https://gitcode.com/gh_mirrors/op/OpenModScan 在工业自动化领域&#xff0c;设备间的通讯可靠性直接决…...

如何利用APOC插件提升Neo4J的数据处理能力?实战配置指南

如何利用APOC插件释放Neo4J的隐藏潜能&#xff1f;高阶实战手册 当你已经熟练使用Cypher进行常规图数据查询时&#xff0c;是否遇到过这些瓶颈&#xff1f;需要批量处理百万级节点关系却找不到高效方法&#xff1b;想实现复杂图算法但原生函数库不支持&#xff1b;数据导入导出…...

基于虚拟局域网技术实现个人影音库的远程高画质流媒体访问

给大家推荐一种利用虚拟局域网&#xff08;Virtual Private Network&#xff0c;但更精确地说是软件定义的二层网络&#xff09;技术&#xff0c;解决个人或家庭搭建的本地影音库&#xff08;通常基于NAS设备&#xff09;在外部网络访问时面临的画质压缩、延迟卡顿及协议兼容性…...