python下实现二叉堆以及堆排序的示例

发布时间 - 2026-01-11 03:28:06    点击率:

堆是一种特殊的树形结构, 堆中的数据存储满足一定的堆序。堆排序是一种选择排序, 其算法复杂度, 时间复杂度相对于其他的排序算法都有很大的优势。

堆分为大头堆和小头堆, 正如其名, 大头堆的第一个元素是最大的, 每个有子结点的父结点, 其数据值都比其子结点的值要大。小头堆则相反。

我大概讲解下建一个树形堆的算法过程:

找到N/2 位置的数组数据, 从这个位置开始, 找到该节点的左子结点的索引, 先比较这个结点的下的子结点, 找到最大的那个, 将最大的子结点的索引赋值给左子结点, 然后将最大的子结点和父结点进行对比, 如果比父结点大, 与父节点交换数据。当然, 我只是大概说了下实现, 在此过程中, 还需要考虑结点不存在的情况。

看下代码:

# 构建二叉堆 
def binaryHeap(arr, lenth, m): 
 temp = arr[m] # 当前结点的值 
 while(2*m+1 < lenth): 
 lchild = 2*m+1 
 if lchild != lenth - 1 and arr[lchild] < arr[lchild + 1]: 
 lchild = lchild + 1 
 if temp < arr[lchild]: 
 arr[m] = arr[lchild] 
 else: 
 break 
 m = lchild 
 arr[m] = temp 
 
 
def heapsort(arr, length): 
 i = int(len(arr)/2) 
 while(i >= 0): 
 binaryHeap(arr, len(arr), i) 
 i = i - 1 
 
 print("二叉堆的物理顺序为:") 
 print(arr) # 输出二叉堆的物理顺序 
 
 
if __name__ == '__main__': 
 arr = [2, 87, 39, 49, 34, 62, 53, 6, 44, 98] 
 
 heapsort(arr, len(arr))

堆排序过程就是依次将最后的结点与首个节点进行对比交换:

# 构建二叉堆
def binaryHeap(arr, lenth, m):
  temp = arr[m] # 当前结点的值
  while(2*m+1 < lenth):
    lchild = 2*m+1
    if lchild != lenth - 1 and arr[lchild] < arr[lchild + 1]:
      lchild = lchild + 1
    if temp < arr[lchild]:
      arr[m] = arr[lchild]
    else:
      break
    m = lchild
  arr[m] = temp


def heapsort(arr, length):
  i = int(len(arr)/2)
  while(i >= 0):
    binaryHeap(arr, len(arr), i)
    i = i - 1

  print("二叉堆的物理顺序为:")
  print(arr) # 输出二叉堆的物理顺序

  i = length-1
  while(i > 0):
    arr[i], arr[0] = arr[0], arr[i] # 变量交换
    binaryHeap(arr, i, 0)
    i = i - 1560


def pop(arr):
  first = arr.pop(0)
  return first


if __name__ == '__main__':
  arr = [2, 87, 39, 49, 34, 62, 53, 6, 44, 98]

  heapsort(arr, len(arr))

  print("堆排序后的物理顺序")
  print(arr) # 输出经过堆排序之后的物理顺序

  data = pop(arr)
  print(data)

  print(arr)

python封装了一个堆模块, 我们使用该模块可以很高效的实现一个优先队列

import heapq


class Item:
  def __init__(self, name):
    self.name = name

  def __repr__(self):
    return 'Item({!r})'.format(self.name)


class PriorityQueue:
  def __init__(self):
    self._queue = []
    self._index = 0

  def push(self, item, priority):
    heapq.heappush(self._queue, (-priority, self._index, item)) # 存入一个三元组
    self._index += 1

  def pop(self):
    return heapq.heappop(self._queue)[-1] # 逆序输出


if __name__ == '__main__':
  p = PriorityQueue()
  p.push(Item('foo'), 1)
  p.push(Item('bar'), 5)
  p.push(Item('spam'), 4)
  p.push(Item('grok'), 1)

  print(p.pop())
  print(p.pop())

具体请看heapq官网

以上这篇python下实现二叉堆以及堆排序的示例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。


# 堆排序  # python实现  # 理解二叉堆数据结构及Swift的堆排序算法实现示例  # Java实现堆排序和图解  # Java实现堆排序(大根堆)的示例代码  # java编程实现优先队列的二叉堆代码分享  # 彻底搞定堆排序:二叉堆  # 小头  # 是一种  # 给大家  # 都有  # 第一个  # 在此  # 说了  # 其他的  # 很高  # 希望能  # 不存在  # 其名  # 还需要  # 这篇  # 相对于  # 首个  # 装了  # 都比  # 小编  # 官网 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Android Socket接口实现即时通讯实例代码  Python函数文档自动校验_规范解析【教程】  如何批量查询域名的建站时间记录?  Laravel如何构建RESTful API_Laravel标准化API接口开发指南  Laravel如何监控和管理失败的队列任务_Laravel失败任务处理与监控  西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?  google浏览器怎么清理缓存_谷歌浏览器清除缓存加速详细步骤  如何在万网利用已有域名快速建站?  Laravel如何处理表单验证?(Requests代码示例)  如何构建满足综合性能需求的优质建站方案?  JavaScript如何实现倒计时_时间函数如何精确控制  Laravel如何实现API版本控制_Laravel版本化API设计方案  php结合redis实现高并发下的抢购、秒杀功能的实例  Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】  谷歌浏览器如何更改浏览器主题 Google Chrome主题设置教程  如何在橙子建站上传落地页?操作指南详解  武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?  Laravel如何配置Horizon来管理队列?(安装和使用)  重庆市网站制作公司,重庆招聘网站哪个好?  简单实现Android文件上传  php打包exe后无法访问网络共享_共享权限设置方法【教程】  如何快速辨别茅台真假?关键步骤解析  北京的网站制作公司有哪些,哪个视频网站最好?  laravel怎么配置Redis作为缓存驱动_laravel Redis缓存配置教程  如何在自有机房高效搭建专业网站?  Laravel Debugbar怎么安装_Laravel调试工具栏配置指南  如何快速搭建高效WAP手机网站吸引移动用户?  Laravel如何使用Eloquent进行子查询  如何快速配置高效服务器建站软件?  android nfc常用标签读取总结  js代码实现下拉菜单【推荐】  Python制作简易注册登录系统  Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】  高防服务器:AI智能防御DDoS攻击与数据安全保障  ,网页ppt怎么弄成自己的ppt?  HTML5打空格有哪些误区_新手常犯的空格使用错误【技巧】  制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?  香港服务器如何优化才能显著提升网站加载速度?  html5源代码发行怎么设置权限_访问权限控制方法与实践【指南】  Laravel怎么定时执行任务_Laravel任务调度器Schedule配置与Cron设置【教程】  Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】  如何在局域网内绑定自建网站域名?  javascript读取文本节点方法小结  详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)  如何打造高效商业网站?建站目的决定转化率  敲碗10年!Mac系列传将迎来「触控与联网」双革新  音乐网站服务器如何优化API响应速度?  JavaScript常见的五种数组去重的方式  php静态变量怎么调试_php静态变量作用域调试技巧【解答】  怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?