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实现相关推荐

  1. java 二叉堆_二叉堆(三)之 Java的实现

    概要 前面分别通过C和C++实现了二叉堆,本章给出二叉堆的Java版本.还是那句话,它们的原理一样,择其一了解即可. 二叉堆的介绍 二叉堆是完全二元树或者是近似完全二元树,按照数据的排列方式可以分为两 ...

  2. Python:实现最优二叉搜索树算法(附完整源码)

    Python:实现最优二叉搜索树算法 import sys from random import randintclass Node:def __init__(self, key, freq):sel ...

  3. 堆(大根堆、小根堆)

    完全二叉堆 堆又可称之为完全二叉堆.这是一个逻辑上基于完全二叉树.物理上一般基于线性数据结构(如数组.向量.链表等)的一种数据结构. 完全二叉树的存储结构 学习过完全二叉树的同学们都应该了解,完全二叉 ...

  4. 前K个高频元素[小根堆和大根堆的使用]

    小根堆 前言 一.前K个高频元素 二.小根堆&大根堆 1.O(KlogN)大根堆 2.O(NlogK)小根堆 总结 参考文献 前言 当题目需要有序性时,果断排序,可二分快速寻找答案,或是利用有 ...

  5. 【数据结构】堆,大根堆,小根堆,优先队列 详解

    目录 堆 1.堆的数组实现 2.小根堆 3.大根堆 4.优先队列 例题 1.SP348 EXPEDI - Expedition(有趣的贪心思路,优先队列) 2.合并果子 堆 要了解堆之前,请先了解树, ...

  6. 堆结构 - 大根堆、小根堆

    在开发语言中,heap在使用层次的名字叫PriorityQueue(优先级队列),PriorityQueue数据结构的名字就叫做堆,底层就是用堆结构实现的. 完全二叉树 空树也算是完全二叉树 每一层都 ...

  7. java 二叉堆_二叉堆的介绍和Java实现

    一.堆和二叉堆 堆,英文名称Heap,所谓二叉堆(也有直接称二叉堆为堆的),本质上是一个完全二叉树,前面也提到过,如果树接近于完全二叉树或者满二叉树,采用顺序存储代价会小一点,因此常见的二叉堆均是顺序 ...

  8. java优先队列二叉_二叉堆与Java中的优先队列

    之前在A*算法演示程序的编码过程中,发现javaScript并没有原生的优先队列,于是去Java中找到了PriorityQueue类,研究了一下源码.Java中的优先队列基于最小二叉堆实现.最小二叉堆 ...

  9. 下拉菜单实现树状结构_二叉索引树(树状数组)的原理

    背景 了解到二叉索引树这个数据结构,是在 leetcode 的 307 题,题目是要求实现一个数据结构,可以返回数组任意区间的和以及更新数组的某个值. 307.Range Sum Query - Mu ...

最新文章

  1. hdu1848(sg函数打表)
  2. pytorch用win还是Linux,如何在Windows系统安装使用机器学习库PyTorch
  3. [导入]做了一个页面静态化小软件,和大家分享,up有分
  4. MySQL(七)联结表
  5. HDU_1541 Stars(树状数组)
  6. linux ubuntu 开启ssh服务,开启SSH服务远程登录ubuntu
  7. Memcache 安装
  8. 2019有的图纸打印出来看不清楚_CAD制图初学入门:CAD打印实用技巧
  9. 物联网领域面临标准挑战
  10. 高等代数——大学高等代数课程创新教材(丘维声)——3.3笔记+习题
  11. 64位win10下usb转485驱动
  12. 《Web安全攻防》学习笔记
  13. 开源技术领域有哪些免费又好用的OA办公软件?最好是.NET平台
  14. 三星note20u计算机功能,三星Note20Ultra隐藏功能有哪些-有哪些使用技巧
  15. java.net.URL初识
  16. 阿里云,DNS(云解析),封装类
  17. WEEK16 周记 限时CSP模拟——区间动态规划_宇宙狗的危机
  18. 路由器密码忘记 五步暴力破解
  19. win10 桌面的的文件都不见了 提示不注销保存都文件都为临时_使用win10不久,C盘只剩下500MB?这样操作,我清理出了30G空间!...
  20. 想让照片更闪耀?20个金色光效景色Lightroom预设不能错过

热门文章

  1. 这是我见过最完美的“docker学习宝典”,阿里云高工熬夜手写,服!
  2. window下配置nginx 及虚拟主机
  3. 含泪整理最优质耳机免抠元素素材,你想要的这里都有
  4. 企业直播该如何做?硬件设备、网络环境、设备连接和观看权限等整个直播流程教程
  5. python爬取”药智数据”网站下疾病分类与代码的所有疾病名称
  6. 用计算机对音频信息进行处理 要将模拟信号,[电脑基础知识]大学计算机第五章.ppt...
  7. win7打印机共享出现0x000006d9错误的解决方法
  8. 一加3t android 7.1,一加3T 7.1 ROM刷机包 7.1.2 Xposed框架主题号码归属地杜比全息来电闪光网...
  9. android百度地图拖拽地图定位,百度地图,拖动地图,定位marker固定在屏幕中心位置...
  10. 中国城市列表 cityList.son