python数据结构之堆(heap)
本篇学习内容为堆的性质、python实现插入与删除操作、堆复杂度表、python内置方法生成堆。
区分堆(heap)与栈(stack):堆与二叉树有关,像一堆金字塔型泥沙;而栈像一个直立垃圾桶,一列下来。
堆(heap)
又被为优先队列(priority queue)。尽管名为优先队列,但堆并不是队列。回忆一下,在队列中,我们可以进行的限定操作是dequeue和enqueue。
dequeue是按照进入队列的先后顺序来取出元素。而在堆中,我们不是按照元素进入队列的先后顺序取出元素的,而是按照元素的优先级取出元素。
性质
堆的实现通过构造二叉堆(binary heap),实为二叉树的一种;由于其应用的普遍性,当不加限定时,均指该数据结构的这种实现。这种数据结构具有以下性质。
- 任意节点小于(或大于)它的所有后裔,最小元(或最大元)在堆的根上(堆序性)。
- 堆总是一棵完全树。即除了最底层,其他层的节点都被元素填满,且最底层尽可能地从左到右填入。
实现
- 堆的主要操作是插入和删除最小元素(元素值本身为优先级键值,小元素享有高优先级)
- 在插入或者删除操作之后,我们必须保持该实现应有的性质: 1. 完全二叉树 2. 每个节点值都小于或等于它的子节点
上浮(Promotion)
情境: 子节点的键值变为比父节点的键值大;如下面添加字节点
消除这种违反项:
- 交换子节点的键和父节点的键
- 重复这个过程直到堆的顺序恢复正常
堆的添加:

def _upheap(self, j):#往上交换
parent = self._parent(j)
if j > 0 and self._data[j] < self._data[parent]:
self._swap(j, parent)
self._upheap(parent)
下沉(Demotion)
情境:父节点的键值变得比子节点(一个或者2个) 的键值还小 ,如下面删除了根节点后拿了个小子节点补充上来的情况
消除这种违反项:
- 把父节点的键值和比它大的子节点的键值做交换
- 重复这个操作直到堆的顺序恢复正常
删除最大值

def _downheap(self, j):#往下交换,递归比较三个值
if self._has_left(j):
left = self._left(j)
small_child = left
if self._has_right(j):
right = self._right(j)
if self._data[right] < self._data[left]:
small_child = right
if self._data[small_child] < self._data[j]:
self._swap(j, small_child)
self._downheap(small_child)
复杂度分析

Python构建堆的代码:
#该heap为min_heap,即根节点为最小值
class PriorityQueueBase:
#抽象基类为堆 class Item:
#轻量级组合来存储堆项目
__slots__ = '_key' , '_value' def __init__ (self, k, v):
self._key = k
self._value = v def __lt__ (self, other): #比较大小
return self._key < other._key def is_empty(self):
return len(self) == 0 def __str__(self):
return str(self._key) class HeapPriorityQueue(PriorityQueueBase): def __init__ (self):
self._data = [ ] def __len__ (self):
return len(self._data) def is_empty(self):
return len(self) == 0 def add(self, key, value): #在后面加上然后加上
self._data.append(self.Item(key, value))
self._upheap(len(self._data) - 1) def min(self):
if self.is_empty():
raise ValueError( "Priority queue is empty." )
item = self._data[0]
return (item._key, item._value) def remove_min(self):
if self.is_empty():
raise ValueError( "Priority queue is empty." )
self._swap(0, len(self._data) - 1)
item = self._data.pop( )
self._downheap(0)
return (item._key, item._value) def _parent(self, j):
return (j - 1) // 2 def _left(self, j):
return 2 * j + 1 def _right(self, j):
return 2 * j + 2 def _has_left(self, j):
return self._left(j) < len(self._data) def _has_right(self, j):
return self._right(j) < len(self._data) def _swap(self, i, j):
self._data[i], self._data[j] = self._data[j], self._data[i] def _upheap(self, j):#往上交换
parent = self._parent(j)
if j > 0 and self._data[j] < self._data[parent]:
self._swap(j, parent)
self._upheap(parent) def _downheap(self, j):#往下交换,递归比较三个值
if self._has_left(j):
left = self._left(j)
small_child = left
if self._has_right(j):
right = self._right(j)
if self._data[right] < self._data[left]:
small_child = right
if self._data[small_child] < self._data[j]:
self._swap(j, small_child)
self._downheap(small_child) heap = HeapPriorityQueue()
heap.add(4, "D")
heap.add(3, "C")
heap.add(1, "A")
heap.add(5, "E")
heap.add(2, "B")
heap.add(7, "G")
heap.add(6, "F")
heap.add(26, "Z") for item in heap._data:
print(item) print("min is: ")
print(heap.min())
print() print("remove min: ")
print(heap.remove_min())
print("Now min is: ")
print(heap.min())
print() print("remove min: ")
print(heap.remove_min())
print("Now min is: ")
print(heap.min())
print() heap.add(1, "A")
print("Now min is: ")
print(heap.min())
print() #输出结果
1
2
3
5
4
7
6
26
min is:
(1, 'A') remove min:
(1, 'A')
Now min is:
(2, 'B') remove min:
(2, 'B')
Now min is:
(3, 'C') Now min is:
(1, 'A')
python内置方法创建堆有两种方式,heappush()和heapify()
'''
heaqp模块提供了堆队列算法的实现,也称为优先级队列算法。
要创建堆,请使用初始化为[]的列表,或者可以通过函数heapify()将填充列表转换为堆。
提供以下功能:
heapq.heappush(堆,项目)
将值项推入堆中,保持堆不变。
heapq.heapify(x)
在线性时间内将列表x转换为堆。
heapq.heappop(堆)
弹出并返回堆中的最小项,保持堆不变。如果堆是空的,则引发IndexError。
'''
import heapq #1 heappush生成堆+ heappop把堆从小到大pop出来
heap = []
data = [1,3,5,7,9,2,4,6,8,0]
for i in data:
heapq.heappush(heap,i)
print(heap) lis = []
while heap:
lis.append(heapq.heappop(heap))
print(lis) #2 heapify生成堆+ heappop把堆从小到大pop出来
data2 = [1,5,3,2,9,5]
heapq.heapify(data2)
print(data2) lis2 = []
while data2:
lis2.append(heapq.heappop(data2))
print(lis2) #输出结果
[0, 1, 2, 6, 3, 5, 4, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 5, 9, 5]
[1, 2, 3, 5, 5, 9]
python数据结构之堆(heap)的更多相关文章
- 算法与数据结构基础 - 堆(Heap)和优先级队列(Priority queue)
堆基础 堆(Heap)是具有这样性质的数据结构:1/完全二叉树 2/所有节点的值大于等于(或小于等于)子节点的值: 图片来源:这里 堆可以用数组存储,插入.删除会触发节点shift_down.shif ...
- 数据结构之堆Heap
1. 概述 堆(也叫优先队列),是一棵完全二叉树,它的特点是父节点的值大于(小于)两个子节点的值(分别称为大顶堆和小顶堆).它常用于管理算法执行过程中的信息,应用场景包括堆排序,优先队列等. 2. 堆 ...
- Python数据结构2-----队列和堆
一.线性结构:栈.队列.双端队列.列表 二.非线性结构:树.图.堆 [算法中看堆是非线性的,因为其相当于完全二叉树,但堆的存储元素是采用线性的顺序表数组来实现的] 三.队列: 1.队列类型:FIFO. ...
- 数据结构 - 堆(Heap)
数据结构 - 堆(Heap) 1.堆的定义 堆的形式满足完全二叉树的定义: 若 i < ceil(n/2) ,则节点i为分支节点,否则为叶子节点 叶子节点只可能在最大的两层出现,而最大层次上的叶 ...
- python数据结构与算法
最近忙着准备各种笔试的东西,主要看什么数据结构啊,算法啦,balahbalah啊,以前一直就没看过这些,就挑了本简单的<啊哈算法>入门,不过里面的数据结构和算法都是用C语言写的,而自己对p ...
- 算法手记 之 数据结构(堆)(POJ 2051)
一篇读书笔记 书籍简评:<ACM/ICPC 算法训练教程>这本书是余立功主编的,代码来自南京理工大学ACM集训队代码库,所以小编看过之后发现确实很实用,适合集训的时候刷题啊~~,当时是听了 ...
- 堆heap和栈Stack(百科)
堆heap和栈Stack 在计算机领域,堆栈是一个不容忽视的概念,堆栈是两种数据结构.堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除.在单片机应用中,堆栈 ...
- iOS中的堆(heap)和栈(stack)的理解
操作系统iOS 中应用程序使用的计算机内存不是统一分配空间,运行代码使用的空间在三个不同的内存区域,分成三个段:“text segment “,“stack segment ”,“heap segme ...
- Python之数据类型-[bisect,heap]
bisect >>> import bisect >>> >>> b = [ 20, 34, 35, 65, 78 ] >>> ...
随机推荐
- 腾讯大数据平台Oceanus: A one-stop platform for real time stream processing powered by Apache Flink
January 25, 2019Use Cases, Apache Flink The Big Data Team at Tencent In recent years, the increa ...
- Hadoop从入门到精通系列之--0.Hadoop生态体系
https://blog.csdn.net/Haidaiya/article/details/84568588#%E4%B8%80%20%E5%A4%A7%E6%95%B0%E6%8D%AE%E7%9 ...
- (一) Getting Started
Elasticsearch is a highly scalable open-source full-text search and analytics engine. It allows you ...
- 基于SpringBoot搭建应用开发框架(二) —— 登录认证
零.前言 本文基于<基于SpringBoot搭建应用开发框架(一)——基础架构>,通过该文,熟悉了SpringBoot的用法,完成了应用框架底层的搭建. 在开始本文之前,底层这块已经有了很 ...
- echarts中饼图显示百分比
通过echarts制作饼图,需要通过鼠标移动到对应的扇形才能才看数值和百分比. 解决这个问题参考的是将鼠标移动到扇形上的显示方法: tooltip : { trigger: ' ...
- 移除Windows图标快捷方式小箭头
以管理员身份运行cmd,输入 reg delete "HKEY_CLASSES_ROOT\lnkfile" /v IsShortcut /f & taskkill /f / ...
- JAVA工程师-蚂蚁金服电话面试
今天5点半接到一个杭州的电话,是蚂蚁金服打来的,当时心里一阵发慌,由于还在上班,就和面试官约定6点下班之后再来.挂完电话,心里忐忑的不行,感觉自己这也没准备好,那也没准备好.剩下半个小时完全没有心思再 ...
- Asp.Net Core SignalR 与微信小程序交互笔记
什么是Asp.Net Core SignalR Asp.Net Core SignalR 是微软开发的一套基于Asp.Net Core的与Web进行实时交互的类库,它使我们的应用能够实时的把数据推送给 ...
- gorose使用示例
package main import ( "fmt" "github.com/gohouse/gorose" //import Gorose _ " ...
- mybatis 使用auto mapping原理实现表间关联
Auto mapping的示例 数据库中有一个person表,结构如下: mysql> desc person; +-------+-------------+------+-----+---- ...