python中堆的使用
相关实现原理
其实 堆 只是将list中的元素位置进行改变以满足堆的数据结构要求即可;
并且每次 增删改 时 都会移动元素位置以保证 满足 堆 特性
所以 堆的 数据结构仍然是 list而已;只是每次对 堆的操作 都需要将list作为参数 传入堆的函数中;
堆的数据结构要求为: i处的元素总是大于位置i // 2处的元素;注意和下标无关
如: 此堆结构: [1.11, 2, 1.5, 3, 8, 5, 4, 6, 7, 11, 9, 10]
则以 第i=6位的数字8为例; 6//2=3得到 第三位数字(i=3) 1.5 < 第6位数字(i=6) 8
示例代码:
# -*- coding: utf-8 -*-
"""
(C) Guangcai Ren <rgc@bvrft.com>
All rights reserved
create time '2021/4/15 09:51'
Usage:
python中堆的使用
其实 堆 只是将list中的元素位置进行改变以满足堆的数据结构要求即可;
并且每次 增删改 时 都会移动元素位置以保证 满足 堆 特性
所以 堆的 数据结构仍然是 list而已;只是每次对 堆的操作 都需要将list作为参数 传入堆的函数中;
堆的数据结构要求为: i处的元素总是大于位置i // 2处的元素;注意和下标无关
如: 此堆结构: [1.11, 2, 1.5, 3, 8, 5, 4, 6, 7, 11, 9, 10]
则以 第i=6位的数字8为例; 6//2=3得到 第三位数字(i=3) 1.5 < 第6位数字(i=6) 8
"""
import heapq
_list = [11, 1, 1.2, 3, 2, 5, 4, 6, 7, 8, 9, 10]
# 将list转为堆,注意 是在原有数据基础上通过改变数据位置,不会产生新的变量
# 也就是说 只是通过改变元素的位置使其满足堆的特性,但实际 数据类型还是list;可以通过 type()查看
heapq.heapify(_list)
print('转换为堆后的数据类型', type(_list), '仍然是list类型')
print(_list)
# 向堆中添加新元素
heapq.heappush(_list, 1.5)
print(_list)
# 取前5个最大的元素
# 查看源码发现,当查询个数等于1时,使用python内置的max()方法;
# 当查询个数>=len(_list)时,使用python内置的sorted()方法;
# 当查询个数 >1且<len(_list)时,使用 heapq自己的查询方法;
largest_5 = heapq.nlargest(5, _list)
print('取前5个最大的元素', largest_5)
# 取前3个最小的元素
# 实现原理 和 nlargest相同
smallest_3 = heapq.nsmallest(3, _list)
print('取前3个最小的元素', smallest_3)
# 从堆中弹出最小的元素
pop_min_num = heapq.heappop(_list)
print('从堆中弹出最小的元素', pop_min_num)
print('最新数据', _list)
# 弹出最小的元素,并将 新元素 压入堆中
pop_min_num = heapq.heapreplace(_list, 1.11)
print('弹出最小的元素,并将 新元素 压入堆中', pop_min_num)
print('将 新元素 压入堆中 的最新数据,', _list)
相对于 list来说,在计算 前N个最大值/最小值 时比较方便;