python下实现二叉堆以及堆排序

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

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

我大概讲解下建一个树形堆的算法过程:
找到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下实现二叉堆以及堆排序的更多相关文章

  1. Java实现的二叉堆以及堆排序详解

    一.前言 二叉堆是一个特殊的堆,其本质是一棵完全二叉树,可用数组来存储数据,如果根节点在数组的下标位置为1,那么当前节点n的左子节点为2n,有子节点在数组中的下标位置为2n+1.二叉堆类型分为最大堆( ...

  2. 数据结构图文解析之:二叉堆详解及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  3. 二叉堆(一)之 图文解析 和 C语言的实现

    概要 本章介绍二叉堆,二叉堆就是通常我们所说的数据结构中"堆"中的一种.和以往一样,本文会先对二叉堆的理论知识进行简单介绍,然后给出C语言的实现.后续再分别给出C++和Java版本 ...

  4. 二叉堆(二)之 C++的实现

    概要 上一章介绍了堆和二叉堆的基本概念,并通过C语言实现了二叉堆.本章是二叉堆的C++实现. 目录1. 二叉堆的介绍2. 二叉堆的图文解析3. 二叉堆的C++实现(完整源码)4. 二叉堆的C++测试程 ...

  5. 二叉堆(三)之 Java的实现

    概要 前面分别通过C和C++实现了二叉堆,本章给出二叉堆的Java版本.还是那句话,它们的原理一样,择其一了解即可. 目录1. 二叉堆的介绍2. 二叉堆的图文解析3. 二叉堆的Java实现(完整源码) ...

  6. 数据结构与算法——优先队列类的C++实现(二叉堆)

    优先队列简单介绍: 操作系统表明上看着是支持多个应用程序同一时候执行.其实是每一个时刻仅仅能有一个进程执行,操作系统会调度不同的进程去执行. 每一个进程都仅仅能执行一个固定的时间,当超过了该时间.操作 ...

  7. ACM学习笔记:二叉堆

    title : 堆 date : 2021-8-3 tags : ACM,数据结构 什么是堆 堆是一棵具有特定性质的二叉树,堆的基本要求是堆中所有结点的值必须大于等于(或小于等于)其孩子结点的值,这也 ...

  8. 二叉堆 及 大根堆的python实现

    Python 二叉堆(binary heap) 二叉堆是一种特殊的堆,二叉堆是完全二叉树或者是近似完全二叉树.二叉堆满足堆特性:父节点的键值总是保持固定的序关系于任何一个子节点的键值,且每个节点的左子 ...

  9. Python实现二叉堆

    Python实现二叉堆 二叉堆是一种特殊的堆,二叉堆是完全二元树(二叉树)或者是近似完全二元树(二叉树).二叉堆有两种:最大堆和最小堆.最大堆:父结点的键值总是大于或等于任何一个子节点的键值:最小堆: ...

随机推荐

  1. 创建银行API

    DECLARE lc_output VARCHAR2(3000); lc_msg_dummy VARCHAR2(3000); lc_return_status VARCHAR2(3000); lc_m ...

  2. Blue Path(基于cocos2dx 3.0)

    猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=498 iTunes下载:http ...

  3. MySQl数据库必会sql语句加强版

    这篇承接上一篇<mysql必会sql语句>:http://blog.csdn.net/qq_32059827/article/details/51763950 这一篇属于加强版,问题和sq ...

  4. 新手学python(3):yield与序列化

    1 Yield生成器 Yield是我在其他语言中没有见过的一个属性,算是python的一大特色,用好之后可以使代码更简洁.考虑一个简单的例子,文件的遍历.要遍历一个目录下的所有文件需要递归的操作.如果 ...

  5. java设计模式---调停者模式

    中介者模式(Mediator):用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互.   通用类图:   举例:在一个公司里面 ...

  6. java设计模式---合成模式3

    实例 下面以一个逻辑树为例子,以上面的原理图为蓝本,看看如何实现并如何使用这个树,这个结构很简单,但是如何去使用树,遍历树.为我所用还是有一定难度的.   这里主要用到树的递归遍历,如何递归.如何控制 ...

  7. Cocos2D中屏幕分辨率解释

    Cocos2D的坐标(0,0)点在屏幕的左下角,然后x和y的坐标值像右上角逐渐增加. 因为项目一般是横屏(landscape)模式,这表示右上角坐标在3.5寸屏上为(480,320), 在4寸屏上为( ...

  8. 从JDK源码角度看线程池原理

    "池"技术对我们来说是非常熟悉的一个概念,它的引入是为了在某些场景下提高系统某些关键节点性能,最典型的例子就是数据库连接池,JDBC是一种服务供应接口(SPI),具体的数据库连接实 ...

  9. iOS中 UITextView文本视图 技术分享

    UITextView: 文本视图相比与UITextField直观的区别就是UITextView可以输入多行文字并且可以滚动显示浏览全文. UITextField的用处多,UITextView的用法也不 ...

  10. UseCase事件流描述规范

    文/fasiondog 整理需求用例的编写规范,分享部分UseCase事件流描述规范.其中,准则5~10.12来自<编写有效用例>([美] Alistair Cockburn 著)一书,其 ...