python最大堆_二叉堆 及 大根堆的python实现
Python
二叉堆(binary heap)
二叉堆是一种特殊的堆,二叉堆是完全二叉树或者是近似完全二叉树。二叉堆满足堆特性:父节点的键值总是保持固定的序关系于任何一个子节点的键值,且每个节点的左子树和右子树都是一个二叉堆。
当父节点的键值总是大于或等于任何一个子节点的键值时为最大堆。 当父节点的键值总是小于或等于任何一个子节点的键值时为最小堆。
二叉堆的存储
二叉堆一般用数组来表示。如果根节点在数组中的位置是1,第n个位置的子节点分别在2n和 2n+1。因此,第1个位置的子节点在2和3,第2个位置的子节点在4和5。以此类推。这种基于1的数组存储方式便于寻找父节点和子节点。
如果存储数组的下标基于0,那么下标为i的节点的子节点是2i + 1与2i + 2;其父节点的下标是?floor((i ? 1) ∕ 2)?, 函数floor(x), 其功能是“向下取整”,或者说“向下舍入”,即取不大于x的最大整数(与“四舍五入”不同,下取整是直接取按照数轴上最接近要求值的左边值,即不大于要求值的最大的那个值)。比如floor(1.1),floor(1.9)都是返回1。
如下图的两个堆:
将这两个堆保存在以1开始的数组中:
位置: 1 2 3 4 5 6 7 8 9 10 11
左图: 1 2 3 4 5 6 7 8 9 10 11
右图: 11 9 10 5 6 7 8 1 2 3 4
对于一个很大的堆,这种存储是低效的。因为节点的子节点很可能在另外一个内存页中。B-heap是一种效率更高的存储方式,把每个子树放到同一内存页。
如果用指针链表存储堆,那么需要能访问叶节点的方法。可以对二叉树“穿线”(threading)方式,来依序遍历这些节点。
基本操作
插入节点
在数组的最末尾插入新节点。然后自下而上调整子节点与父节点(称作up-heap或bubble-up, percolate-up, sift-up, trickle up, heapify-up, cascade-up操作):比较当前节点与父节点,不满足堆性质则交换。从而使得当前子树满足二叉堆的性质。时间复杂度为O(log n)。
删除节点
删除根节点用于堆排序。
对于最大堆,删除根节点就是删除最大值;对于最小堆,是删除最小值。然后,把堆存储的最后那个节点移到填在根节点处。再从上而下调整父节点与它的子节点:对于最大堆,父节点如果小于具有最大值的子节点,则交换二者。这一操作称作down-heap或bubble-down, percolate-down, sift-down, trickle down, heapify-down, cascade-down,extract-min/max等。直至当前节点与它的子节点满足堆性质为止。
构造二叉堆
一个直观办法是从单节点的二叉堆开始,每次插入一个节点。其时间复杂度为 {\displaystyle O(n\log n)} O(n\log n)。
最优算法是从一个节点元素任意放置的二叉树开始,自底向上对每一个子树执行删除根节点时的Max-Heapify算法(这是对最大堆而言)使得当前子树成为一个二叉堆。具体而言,假设高度为h的子树均已完成二叉堆化,那么对于高度为h+1的子树,把其根节点沿着最大子节点的分枝做调整,最多需要h步完成二叉堆化。可以证明,这个算法的时间复杂度为O(n)。
代码
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
@author: gsharp
"""
class BinaryHeap:
def __init__(self, n):
self.heap = [0] * n
self.size = 0
def remove_min(self):
removed = self.heap[0]
self.size -= 1
self.heap[0] = self.heap[self.size]
self._down(0)
return removed
def add(self, value):
self.heap[self.size] = value
self._up(self.size)
self.size += 1
def _up(self, pos):
while pos > 0:
parent = (pos - 1) // 2
if self.heap[pos] >= self.heap[parent]:
break
self.heap[pos], self.heap[parent] = self.heap[parent], self.heap[pos]
pos = parent
def _down(self, pos):
while True:
child = 2 * pos + 1
if child >= self.size:
break
if child + 1 < self.size and self.heap[child + 1] < self.heap[child]:
child += 1
if self.heap[pos] <= self.heap[child]:
break
self.heap[pos], self.heap[child] = self.heap[child], self.heap[pos]
pos = child
def test():
h = BinaryHeap(10)
h.add(5)
h.add(7)
h.add(9)
h.add(4)
h.add(3)
print(h.heap)
h.add(1)
print(h.heap)
h.add(2)
print(h.heap)
print(h.remove_min())
print(h.remove_min())
print(h.remove_min())
test()
python最大堆_二叉堆 及 大根堆的python实现相关推荐
- java 二叉堆_二叉堆(三)之 Java的实现
概要 前面分别通过C和C++实现了二叉堆,本章给出二叉堆的Java版本.还是那句话,它们的原理一样,择其一了解即可. 二叉堆的介绍 二叉堆是完全二元树或者是近似完全二元树,按照数据的排列方式可以分为两 ...
- Python:实现最优二叉搜索树算法(附完整源码)
Python:实现最优二叉搜索树算法 import sys from random import randintclass Node:def __init__(self, key, freq):sel ...
- 堆(大根堆、小根堆)
完全二叉堆 堆又可称之为完全二叉堆.这是一个逻辑上基于完全二叉树.物理上一般基于线性数据结构(如数组.向量.链表等)的一种数据结构. 完全二叉树的存储结构 学习过完全二叉树的同学们都应该了解,完全二叉 ...
- 前K个高频元素[小根堆和大根堆的使用]
小根堆 前言 一.前K个高频元素 二.小根堆&大根堆 1.O(KlogN)大根堆 2.O(NlogK)小根堆 总结 参考文献 前言 当题目需要有序性时,果断排序,可二分快速寻找答案,或是利用有 ...
- 【数据结构】堆,大根堆,小根堆,优先队列 详解
目录 堆 1.堆的数组实现 2.小根堆 3.大根堆 4.优先队列 例题 1.SP348 EXPEDI - Expedition(有趣的贪心思路,优先队列) 2.合并果子 堆 要了解堆之前,请先了解树, ...
- 堆结构 - 大根堆、小根堆
在开发语言中,heap在使用层次的名字叫PriorityQueue(优先级队列),PriorityQueue数据结构的名字就叫做堆,底层就是用堆结构实现的. 完全二叉树 空树也算是完全二叉树 每一层都 ...
- java 二叉堆_二叉堆的介绍和Java实现
一.堆和二叉堆 堆,英文名称Heap,所谓二叉堆(也有直接称二叉堆为堆的),本质上是一个完全二叉树,前面也提到过,如果树接近于完全二叉树或者满二叉树,采用顺序存储代价会小一点,因此常见的二叉堆均是顺序 ...
- java优先队列二叉_二叉堆与Java中的优先队列
之前在A*算法演示程序的编码过程中,发现javaScript并没有原生的优先队列,于是去Java中找到了PriorityQueue类,研究了一下源码.Java中的优先队列基于最小二叉堆实现.最小二叉堆 ...
- 下拉菜单实现树状结构_二叉索引树(树状数组)的原理
背景 了解到二叉索引树这个数据结构,是在 leetcode 的 307 题,题目是要求实现一个数据结构,可以返回数组任意区间的和以及更新数组的某个值. 307.Range Sum Query - Mu ...
最新文章
- hdu1848(sg函数打表)
- pytorch用win还是Linux,如何在Windows系统安装使用机器学习库PyTorch
- [导入]做了一个页面静态化小软件,和大家分享,up有分
- MySQL(七)联结表
- HDU_1541 Stars(树状数组)
- linux ubuntu 开启ssh服务,开启SSH服务远程登录ubuntu
- Memcache 安装
- 2019有的图纸打印出来看不清楚_CAD制图初学入门:CAD打印实用技巧
- 物联网领域面临标准挑战
- 高等代数——大学高等代数课程创新教材(丘维声)——3.3笔记+习题
- 64位win10下usb转485驱动
- 《Web安全攻防》学习笔记
- 开源技术领域有哪些免费又好用的OA办公软件?最好是.NET平台
- 三星note20u计算机功能,三星Note20Ultra隐藏功能有哪些-有哪些使用技巧
- java.net.URL初识
- 阿里云,DNS(云解析),封装类
- WEEK16 周记 限时CSP模拟——区间动态规划_宇宙狗的危机
- 路由器密码忘记 五步暴力破解
- win10 桌面的的文件都不见了 提示不注销保存都文件都为临时_使用win10不久,C盘只剩下500MB?这样操作,我清理出了30G空间!...
- 想让照片更闪耀?20个金色光效景色Lightroom预设不能错过
热门文章
- 这是我见过最完美的“docker学习宝典”,阿里云高工熬夜手写,服!
- window下配置nginx 及虚拟主机
- 含泪整理最优质耳机免抠元素素材,你想要的这里都有
- 企业直播该如何做?硬件设备、网络环境、设备连接和观看权限等整个直播流程教程
- python爬取”药智数据”网站下疾病分类与代码的所有疾病名称
- 用计算机对音频信息进行处理 要将模拟信号,[电脑基础知识]大学计算机第五章.ppt...
- win7打印机共享出现0x000006d9错误的解决方法
- 一加3t android 7.1,一加3T 7.1 ROM刷机包 7.1.2 Xposed框架主题号码归属地杜比全息来电闪光网...
- android百度地图拖拽地图定位,百度地图,拖动地图,定位marker固定在屏幕中心位置...
- 中国城市列表 cityList.son