我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python实现最大堆(大顶堆)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Python实现最大堆(大顶堆)

最大堆是指最大的元素在堆顶的堆。

Python自带的heapq模块实现的是最小堆,没有提供最大堆的实现。虽然有些文章通过把元素取反再放入堆,出堆时再取反,把问题转换为最小堆问题也能间接实现最大堆,但是这样的实现只适合数值型的元素,不适合自定义类型。

下面给出实现代码:

# -*- coding: UTF-8 -*- 
                
import random


class MaxHeap(object):

    def __init__(self):
        self._data = []
        self._count = len(self._data)

    def size(self):
        return self._count

    def isEmpty(self):
        return self._count == 0

    def add(self, item):
        # 插入元素入堆
        self._data.append(item)
        self._count += 1
        self._shiftup(self._count-1)

    def pop(self):
        # 出堆
        if self._count > 0:
            ret = self._data[0]
            self._data[0] = self._data[self._count-1]
            self._count -= 1
            self._shiftDown(0)
            return ret
        
    def _shiftup(self, index):
        # 上移self._data[index],以使它不大于父节点
        parent = (index-1)>>1
        while index > 0 and self._data[parent] < self._data[index]:
            # swap
            self._data[parent], self._data[index] = self._data[index], self._data[parent]
            index = parent
            parent = (index-1)>>1

    def _shiftDown(self, index):
        # 上移self._data[index],以使它不小于子节点
        j = (index << 1) + 1
        while j < self._count :
            # 有子节点
            if j+1 < self._count and self._data[j+1] > self._data[j]:
                # 有右子节点,并且右子节点较大
                j += 1
            if self._data[index] >= self._data[j]:
                # 堆的索引位置已经大于两个子节点,不需要交换了
                break
            self._data[index], self._data[j] = self._data[j], self._data[index]
            index = j
            j = (index << 1) + 1

# 元素是数值类型                
def testIntValue():
    for iTimes in range(10):
        iLen = random.randint(1,300)
        allData= random.sample(range(iLen*100), iLen)
#         allData = [1, 4, 3, 2, 5, 7, 6]
#         iLen = len(allData)
        print('\nlen =',iLen)
        
        oMaxHeap = MaxHeap()
        print('_data:\t   ', allData)
        arrDataSorted = sorted(allData, reverse=True)
        print('dataSorted:', arrDataSorted)
        for i in allData:
            oMaxHeap.add(i)
        heapData = []    
        for i in range(iLen):
            iExpected = arrDataSorted[i]
            iActual = oMaxHeap.pop()
            heapData.append(iActual)
            print('{0}, expected: {1}, actual: {2}'.format(iExpected==iActual, iExpected, iActual))
            assert iExpected==iActual, ""
        print('dataSorted:', arrDataSorted)
        print('heapData:  ',heapData)
        
# 元素是元祖类型
def testTupleValue():
    for iTimes in range(10):
        iLen = random.randint(1,300)
        listData= random.sample(range(iLen*100), iLen)
#         listData = [1, 4, 3, 2, 5, 7, 6]
#         iLen = len(listData)
        # 注意:key作为比较大小的关键
        allData = dict(zip(listData, [str(e) for e in listData]))
        print('\nlen =',iLen)
        print('allData: ', allData)
        
        oMaxHeap = MaxHeap()
        arrDataSorted = sorted(allData.items(), key=lambda d:d[0], reverse=True)
#         arrDataSorted = sorted(allData, reverse=True)
        print('dataSorted:', arrDataSorted)
        for (k,v) in allData.items():
            oMaxHeap.add((k,v)) # 元祖的第一个元素作为比较点
        heapData = []    
        for i in range(iLen):
            iExpected = arrDataSorted[i]
            iActual = oMaxHeap.pop()
            heapData.append(iActual)
            print('{0}, expected: {1}, actual: {2}'.format(iExpected==iActual, iExpected, iActual))
            assert iExpected==iActual, ""
        print('dataSorted:', arrDataSorted)
        print('heapData:  ',heapData)
        
# 元素是自定义类    
def testClassValue():
    
    class Model4Test(object):
        '''
        用于放入到堆的自定义类。注意要重写__lt__、__ge__、__le__和__cmp__函数。
        '''
        def __init__(self, sUid, value):
            self._sUid = sUid
            self._value = value
        
        def getUid(self):
            return self._sUid
        
        def getValue(self):
            return self._value
        
        # 类类型,使用的是小于号_lt_
        def __lt__(self, other):#operator < 
#             print('in __lt__(self, other)')
            return self.getValue() < other.getValue()
       
        def __ge__(self,other):#oprator >=
            return self.getValue() >= other.getValue()
     
        #下面两个方法重写一个就可以了
        def __le__(self,other):#oprator <=
            return self.getValue() <= other.getValue()
         
        def __cmp__(self,other):
            #call global(builtin) function cmp for int
            return super.cmp(self.getValue(),other.getValue())
        
        def __str__(self):
            return '({0}, {1})'.format(self._value, self._sUid)
            
    for iTimes in range(10):
        iLen = random.randint(1,300)
        listData = random.sample(range(iLen*100), iLen)
#         listData = [1, 4, 3, 2, 5, 7, 6]
        allData = [Model4Test(str(value), value) for value in listData]
        print('allData:   ', [str(e) for e in allData])
        iLen = len(allData)
        print('\nlen =',iLen)

        oMaxHeap = MaxHeap()
        arrDataSorted = sorted(allData, reverse=True)
        print('dataSorted:', [str(e) for e in arrDataSorted])
        for i in allData:
            oMaxHeap.add(i)
        heapData = []    
        for i in range(iLen):
            iExpected = arrDataSorted[i]
            iActual = oMaxHeap.pop()
            heapData.append(iActual)
            print('{0}, expected: {1}, actual: {2}'.format(iExpected==iActual, iExpected, iActual))
            assert iExpected==iActual, ""
        print('dataSorted:', [str(e) for e in arrDataSorted])
        print('heapData:  ', [str(e) for e in heapData])
                        
if __name__ == '__main__':
    testIntValue()
    testTupleValue()
    testClassValue()

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Python实现最大堆(大顶堆)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python实现最大堆(大顶堆)

最大堆是指最大的元素在堆顶的堆。Python自带的heapq模块实现的是最小堆,没有提供最大堆的实现。虽然有些文章通过把元素取反再放入堆,出堆时再取反,把问题转换为最小堆问题也能间接实现最大堆,但是这样的实现只适合数值型的元素,不适合自定义
2023-01-31

Java 堆排序实例(大顶堆、小顶堆)

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序的平均时间复杂度为Ο(nlogn) 。算法步骤:1. 创建
2023-05-30

Java如何实现二叉堆、大顶堆和小顶堆

这篇文章将为大家详细讲解有关Java如何实现二叉堆、大顶堆和小顶堆,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。什么是二叉堆二叉堆就是完全二叉树,或者是靠近完全二叉树结构的二叉树。在二叉树建树时采取前序建
2023-06-29

【算法——Python实现】最大堆和最小

# _*_ encoding:utf-8 _*_"""最大堆"""class MaxHeap(object): # def __init__(self): # self.data = [] # 创建堆 # sel
2023-01-31

Java语言如何实现最大堆

这篇文章将为大家详细讲解有关Java语言如何实现最大堆,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。最大堆最大堆的特点是父元素比子元素大,并且是一棵完全二叉树。data[1]开始存,data[0]空着不用
2023-05-30

Python实现二叉堆

优先队列的二叉堆实现 在前面的章节里我们学习了“先进先出”(FIFO)的数据结构:队列(Queue)。队列有一种变体叫做“优先队列”(Priority Queue)。优先队列的出队(Dequeue)操作和队列一样,都是从队首出队。但在优先队
2022-06-04

python内置堆如何实现

本篇内容介绍了“python内置堆如何实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.简介堆,又称优先队列,是一个完全二叉树,它的每个
2023-07-05

python+opencv怎么实现堆叠图片

这篇文章主要讲解了“python+opencv怎么实现堆叠图片”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“python+opencv怎么实现堆叠图片”吧!代码如下:# import cv2
2023-06-30

python堆排序算法怎么实现

堆排序算法的实现步骤如下:构建最大堆(Max Heap):首先将待排序的序列构建成一个最大堆。从最后一个非叶子节点开始,依次将当前节点与其子节点进行比较,如果当前节点的值小于子节点的值,则将两者交换位置,并继续比较下一个子节点,直到当前节点
2023-10-26

Python实现堆排序的方法详解

本文实例讲述了Python实现堆排序的方法。分享给大家供大家参考,具体如下: 堆排序作是基本排序方法的一种,类似于合并排序而不像插入排序,它的运行时间为O(nlogn),像插入排序而不像合并排序,它是一种原地排序算法,除了输入数组以外只占用
2022-06-04

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录