目录

0.什么是堆

1.最大堆的实现

2.最小堆的实现

3.堆排序

0.什么是堆

小堆和大堆分为如下图:

堆需要满足的条件:

1. 必须是二叉树,且必须是完全二叉树

2. 各个父节点必须大于或小于左右结点, 其中最顶层的根结点必须是最大或者最小的

堆可以使用list实现,就是按照层序遍历顺序将每个节点上的值存放在数组中。父节点和子节点之间存在如下的关系:
i 从0 开始
 parent = (i-1) // 2; left = 2*i + 1 ; right = 2*(i+1)

1.最大堆的实现

堆使用数组的形式表示,不需要使用指针

2. 在堆中增加元素

3,删除根节点,并重建堆结构

#最大堆的实现
class MaxHeap():def __init__(self, maxSize=None):self.maxSize = maxSize self.li = [None] * maxSizeself.count = 0def length(self):#求数组的长度return self.count def show(self):if self.count <= 0:print('null')else:print(self.li[: self.count])def add(self, value):if self.count >= self.maxSize: #判断是否数组越界raise Exception('full')self.li[self.count] = value #将新节点增加到最后self._shift_up(self.count) # 递归构建大堆self.count += 1def _shift_up(self, index):#往大堆中添加元素,并保证根节点是最大的值:#1.增加新的值到最后一个结点,在add实现; 2.与父节点比较,如果比父节点值大,则交换if index > 0:parent = (index - 1) // 2 # 找到根节点if self.li[index] > self.li[parent]: #交换结点self.li[index], self.li[parent] = self.li[parent], self.li[index]self._shift_up(parent) #继续递归从底往上判断def extract(self):    #弹出最大堆的根节点,即最大值#1.删除根结点,将最后一个结点作为更结点 ; 2.判断根结点与左右结点的大小,交换左右结点较大的if not self.count:raise Exception('null')value = self.li[0] self.count -= 1self.li[0] = self.li[self.count]  #将最后一个值变为第一个self._shift_down(0)return valuedef _shift_down(self, index):# 1.判断是否有左子节点并左大于根,左大于右;2.判断是否有右子节点,右大于根left = 2 * index +1right = 2 * index + 2largest = index #判断条件
# 下面2个条件包含了,判断左右结点那个大的情况。如果为3, 4, 5,:
第一个判断条件使得largest=1,再执行第二个条件,则判断其左结点与右结点的大小if left < self.length() and self.li[left] > self.li[largest]:largest = leftif right < self.length() and self.li[right] > self.li[largest]:largest = rightif largest != index: # 将 两者交换self.li[index], self.li[largest] = self.li[largest], self.li[index]self._shift_down(largest)m = MaxHeap(10)
import numpy as np
np.random.seed(123)
num = np.random.randint(100, size =10) #创建随机的10个数
print(m.length())
for i in num:m.add(i)
m.show()
print(m.length())
for i in range(5):print(m.extract(), end=' ,') 

2.最小堆的实现

#构造最小堆
class MinHeap():def __init__(self, maxSize=None):self.maxSize = maxSize self.array = [None] * maxSize self._count = 0def length(self):return self._count def show(self):if self._count <= 0:print('null')print(self.array[: self._count], end=', ')def add(self, value):#增加元素if self._count >= self.maxSize:raise Exception('The array is Full')self.array[self._count] = valueself._shift_up(self._count)self._count += 1def _shift_up(self, index):#比较结点与根节点的大小, 较小的为根结点if index > 0:parent = (index - 1) // 2if self.array[parent] > self.array[index]:self.array[parent], self.array[index] = self.array[index], self.array[parent]self._shift_up(parent)def extract(self):           #获取最小值,并更新数组if self._count <= 0:raise Exception('The array is Empty')value = self.array[0]self._count -= 1 #更新数组的长度self.array[0] = self.array[self._count] #将最后一个结点放在前面self._shift_down(0)return value def _shift_down(self, index):  #此时index 是根结点if index < self._count:left = 2 * index + 1right = 2 * index + 2#判断左右结点是否越界,是否小于根结点,如果是这交换if left < self._count and right < self._count and self.array[left] < self.array[index] and self.array[left] < self.array[right]:self.array[index], self.array[left] = self.array[left], self.array[index] #交换得到较小的值self._shift_down(left)elif left < self._count and right < self._count and self.array[right] < self.array[left] and self.array[right] < self.array[index]:self.array[right], self.array[index] = self.array[index], self.array[right]self._shift_down(right)#特殊情况: 如果只有做叶子结点if left < self._count and right > self._count and self.array[left] < self.array[index]:self.array[left], self.array[index] = self.array[index], self.array[left]self._shift_down(left)mi = MinHeap(10)
print()
print('-------小顶堆----------')
for i in num:mi.add(i)
mi.show()
print(mi.length())
for _ in range(len(num)):print(mi.extract(), end=', ')
print()
print(mi.length())

参考:https://blog.csdn.net/qq_23869697/article/details/82735088

https://python-data-structures-and-algorithms.readthedocs.io/zh/latest/15_%E5%A0%86%E4%B8%8E%E5%A0%86%E6%8E%92%E5%BA%8F/heap_and_heapsort/#_4

3.堆排序

def maxHeapfy(alist, length, parent):left = 2 * parent + 1right = 2 * parent + 2largest = parentif left < length and alist[left] > alist[largest]:largest = leftif right < length and alist[right] > alist[largest]:largest = rightif largest != parent:alist[largest], alist[parent] = alist[parent], alist[largest]maxHeapfy(alist, length, largest)  # 递归构建def buildMaxHeap(alist):  # 构建最大堆n = len(alist)lastParent = (n-1) // 2for i in range(lastParent, -1, -1):maxHeapfy(alist, n, i)def heapSort(alist):buildMaxHeap(alist)n = len(alist)for i in range(n-1, -1, -1):alist[0], alist[i] = alist[i], alist[0]  # 将最大值放在最后面maxHeapfy(alist, i, 0)return alista = [30,50,57,77,62,78,94,80,84]
print(a)
print(heapSort(a))
alist = [2, 4, 1, 2, 5, 58, 45, 24, 67]
print(heapSort(alist))
b = [random.randint(1,1000) for i in range(1000)]
print(b)
print(heapSort(b))

项目推荐:

2000多G的计算机各行业电子资源分享(持续更新)

2020年微信小程序全栈项目之喵喵交友【附课件和源码】

Spring Boot开发小而美的个人博客【附课件和源码】

Java微服务实战296集大型视频-谷粒商城【附代码和课件】

Java开发微服务畅购商城实战【全357集大项目】-附代码和课件

最全最详细数据结构与算法视频-【附课件和源码】

python实现最大堆,最小堆和堆排序相关推荐

  1. java 最小堆_堆排序 最大堆 最小堆 Java 实现

    堆 一点疑惑,堆排序是就地排序,所以空间复杂度是 O(1).但是,比如我有一个数组,建立一个最小堆,然后每次取出最小堆的顶点.建立最小堆需要额外空间? 不深究了,归并排序需要额外空间. 堆是完全二叉树 ...

  2. C++实现最大堆最小堆

    目录 堆和栈的区别 最大堆与最小堆 最大堆的操作 最大堆的插入操作 最大堆的弹出操作 最大堆的C++代码实现 最小堆概念 最小堆的插入操作 最小堆的弹出操作 最小堆的C++代码实现 最大堆最小堆的应用 ...

  3. Golang实现最大堆/最小堆

    Golang实现最大堆/最小堆 参考: https://yangjiahao106.github.io/2019/01/15/golang-%E6%9C%80%E5%A4%A7%E5%A0%86%E5 ...

  4. 深入理解堆(最大堆,最小堆及堆排序)

    基本概念: 1.完全二叉树:若二叉树的深度为h,则除第h层外,其他层的结点全部达到最大值,且第h层的所有结点都集中在左子树. 2.满二叉树:满二叉树是一种特殊的的完全二叉树,所有层的结点都是最大值. ...

  5. C++STL中的最大堆,最小堆

    堆,优先队列,头文件和队列是同一个#include<queue> #include<iostream> #include<queue> using namespac ...

  6. 最大堆最小堆的实现(C语言)

    ---------------- 该篇文章经提醒有一些错误,暂时没有时间修改,请勿参考. 该篇文章经提醒有一些错误,暂时没有时间修改,请勿参考. ---------------- 堆是特殊的队列,从堆 ...

  7. C++ 最大堆最小堆与push_heap pop_heap

    make_heap:根据不同参数生成大顶堆或者小顶堆,默认大顶堆. make_heap(_RAIter,_RAIter) 默认生成大顶堆 make_heap(_RAIter,_RAIter,_Comp ...

  8. python 中的最大堆和最小堆(heapq库)

    目录 首先来看一下什么是最大堆和最小堆? python heapq库中的一些常用方法 小试牛刀 首先来看一下什么是最大堆和最小堆? 最大堆:一种经过排序的完全二叉树,其中任意非终端节点数值均不小于其左 ...

  9. WebServer代码解读(3)【最小堆定时器与队列】

    文章目录 1 - 处理事件 1-1 接收新连接 1-2 最小堆定时器 1-4 将request加入线程池 1-5 处理request 1 - 处理事件 因为epoll_wait函数已经返回了需要处理的 ...

最新文章

  1. bp神经网络算法步流程_基于遗传算法的BP神经网络优化算法模板
  2. python爬虫有什么用处-Python爬虫的作用与地位(附爬虫技术路线图)
  3. python 冒泡排序_Python中的冒泡排序
  4. matlab敏感词输出代码,敏感词设置
  5. 一、自然语言处理概述
  6. zookeeper 命令
  7. 微信公众平台开发——问题篇
  8. 牛客假日团队赛10 L 乘积最大 (dp,大数)
  9. 论文信息系统项目管理的进度管理
  10. fcn从头开始_如何使用Go从头开始构建区块链
  11. [Java] 蓝桥杯ALGO-10 算法训练 集合运算
  12. IntelliJ IDEA 12 与 Tomcat7 配置
  13. 【Java后台开发规范】--- Null值处理
  14. UNIX编程艺术-艾瑞克.S.理曼德
  15. 证明费马最后定理的英国数学家,终获2016阿贝尔奖
  16. 为什么安装MathType无法复制粘贴
  17. 裸奔的智能插座:博联Broadlink SP2/SP mini的分析、破解
  18. 排列组合思维导图_Xmind 进阶教程|高级感满满的思维导图都在使用的6个技巧。...
  19. 利用 @media screen 实现网页布局的自适应,@media screen and
  20. 各个级别的教师资格证分别可以教什么阶段

热门文章

  1. 解决Android Studio运行模拟器报:The emulator process for AVD Pixel_4a_Edited_API_28 has terminated.
  2. 在制定调薪计划和沟通薪果时我们到底该做么
  3. Aja5 - 请求PHP数据
  4. Chrome 如何访问手机站?
  5. SCL定时 1500_iPhone12开售当天黄牛加价1500,哪里买最划算?_
  6. 更改mysql表显示数据条数_layui数据表格自定义每页条数limit设置
  7. 标题不劲爆,点进来看你就知道——3DMAX室内效果图展示
  8. 用python递归求兔子总量_在Python中优化递归Padovan(即Fibonacci和垂死的兔子)算法...
  9. 智能客服系统都能帮企业做哪些事
  10. IOS系统input边框问题