最小堆实现优先队列:Python实现

简介: 堆是一种数据结构,因为Heapsort而被提出。除了堆排序,“堆”这种数据结构还可以用于优先队列的实现。 堆首先是一个完全二叉树:它除了最底层之外,树的每一层的都是满的,且最底层中的节点处于左边,相互之间没有“跳变”;其次,堆有次序属性:每个节点中的数据项都大于或者等于其子女的数据项(如果是记录,则这些记录中的某个关键域必须满足这一属性)。

堆是一种数据结构,因为Heapsort而被提出。除了堆排序,“堆”这种数据结构还可以用于优先队列的实现。

堆首先是一个完全二叉树:它除了最底层之外,树的每一层的都是满的,且最底层中的节点处于左边,相互之间没有“跳变”;其次,堆有次序属性:每个节点中的数据项都大于或者等于其子女的数据项(如果是记录,则这些记录中的某个关键域必须满足这一属性)。 当然,这是指大顶堆,小顶堆则是父节点比子节点都要小。

所谓队列,就是一个FIFO表(first in, first out)。优先队列,就是在队列的基础上,每个元素加一个优先级,last in的元素可能会first out,这就是优先级在起作用。

我想实现这样一个优先队列:

  元素为整数

  元素值小的优先级反而大

  有入队操作,每次进入一个元素

  出队操作,也行每次一个元素

那么,我的小根堆Heap应该这样考虑:

  每当插入元素时,在原有Heap的最后一个叶子节点后面插入新元素val,并持续比较val和其父节点的值之间是否满足堆的次序属性,直到满足

  每当删除元素时,删除的是值最小的元素,也就是根结点root,则将root和最后一个叶子节点lastleaf互换,然后删除交换后的new_lastleaf ,并从new_root开始调整堆,使满足堆的次序属性。

这样一来,代码就不难写出:

#coding:utf8
#author:HaxtraZ
#description:优先队列,用堆实现
#修改自《算法导论》2nd Edition


class ZHeap:
    def __init__(self, item=[]):
        # 初始化。item为数组
        self.items = item
        self.heapsize = len(self.items)

    def LEFT(self, i):
        return 2 * i + 1

    def RIGHT(self, i):
        return 2 * i + 2

    def PARENT(self, i):
        return (i - 1) / 2

    def MIN_HEAPIFY(self, i):
        # 最小堆化:使以i为根的子树成为最小堆
        l = self.LEFT(i)
        r = self.RIGHT(i)
        if l < self.heapsize and self.items[l] < self.items[i]:
            smallest = l
        else:
            smallest = i

        if r < self.heapsize and self.items[r] < self.items[smallest]:
            smallest = r

        if smallest != i:
            self.items[i], self.items[smallest] = self.items[smallest], self.items[i]
            self.MIN_HEAPIFY(smallest)

    def INSERT(self, val):
        # 插入一个值val,并且调整使满足堆结构
        self.items.append(val)
        idx = len(self.items) - 1
        parIdx = self.PARENT(idx)
        while parIdx >= 0:
            if self.items[parIdx] > self.items[idx]:
                self.items[parIdx], self.items[idx] = self.items[idx], self.items[parIdx]
                idx = parIdx
                parIdx = self.PARENT(parIdx)
            else:
                break
        self.heapsize += 1

    def DELETE(self):
        last = len(self.items) - 1
        if last < 0:
            # 堆为空
            return None
        # else:
        self.items[0], self.items[last] = self.items[last], self.items[0]
        val = self.items.pop()
        self.heapsize -= 1
        self.MIN_HEAPIFY(0)
        return val


    def BUILD_MIN_HEAP(self):
        # 建立最小堆, O(nlog(n))
        i = self.PARENT(len(self.items) - 1)
        while i >= 0:
            self.MIN_HEAPIFY(i)
            i -= 1

    def SHOW(self):
        print self.items


class ZPriorityQ(ZHeap):
    def __init__(self, item=[]):
        ZHeap.__init__(self, item)

    def enQ(self, val):
        ZHeap.INSERT(self, val)

    def deQ(self):
        val = ZHeap.DELETE(self)
        return val


a = [1, 3, 2, 4, 8, 6, 22, 9]
pq = ZPriorityQ()
n = len(a)
for i in range(n):
    pq.enQ(a[i])
    pq.SHOW()

for i in range(n):
    pq.deQ()
    pq.SHOW()

  其中,ZHeap表示小根堆,ZPriorityQ表示优先队列,deQ表示退队,enQ表示入队。

  我们发现以下结论:大根堆用于升序排序,小根堆用于降序排序。

  为什么用堆来实现优先队列?原因只有一个:复杂度低。

    如果使用列表(存放在list中),插入为O(1),删除为O(n);

    如果使用按照优先级排好序的有序列表,插入和线性插入排序一样,O(n),删除则为O(1)

  使用堆的时候,无论你删除还是插入,都是O(lg n)时间复杂度,对于插入和删除都比较频繁的操作来讲,这是最好不过的了。

 

  如果认为有不正确的地方欢迎拍砖。

目录
相关文章
|
算法 安全 大数据
揭秘!Python堆与优先队列:数据结构的秘密武器,让你的代码秒变高效战士!
【7月更文挑战第8天】Python的heapq模块和queue.PriorityQueue提供堆与优先队列功能,助你提升算法效率。堆用于快速找大数据集的第K大元素,如示例所示,时间复杂度O(n log k)。PriorityQueue在多线程中智能调度任务,如模拟下载管理器,按优先级处理任务。掌握这些工具,让代码运行更高效!
168 1
|
算法 大数据 数据处理
震撼!Python堆与优先队列的神奇力量,让你的数据处理能力瞬间爆表!
【7月更文挑战第9天】Python的heapq模块实现了堆数据结构,用于高效地插入、删除和查找最大/最小元素。在Top K元素查找中,堆能快速找到大数据集的前k个最大值。同样,堆作为优先队列,按优先级而非入队顺序处理任务,如任务调度,展示其在复杂问题解决中的效率。掌握这些工具,能显著提升数据处理和编程效率。
119 3
|
存储 算法 调度
惊呆了!Python高级数据结构堆与优先队列,竟然能这样优化你的程序性能!
【7月更文挑战第10天】Python的heapq模块实现了堆和优先队列,提供heappush和heappop等函数,支持O(log n)时间复杂度的操作。优先队列常用于任务调度和图算法,优化性能。例如,Dijkstra算法利用最小堆加速路径查找。堆通过列表存储,内存效率高。示例展示了添加、弹出和自定义优先级元素。使用堆优化程序,提升效率。
180 2
|
存储 大数据 程序员
逆袭吧,程序员!Python堆与优先队列的使用秘籍,助你轻松解决复杂问题!
【7月更文挑战第9天】Python的堆和优先队列是高效工具,对比列表在删除最小元素时的O(n)复杂度,堆提供O(log n)操作。优先队列利用堆数据结构,按优先级处理元素,而非FIFO。示例中,heapq模odule创建最小堆实现任务优先级执行,显示了其在解决复杂问题时的威力,助力程序员提升效率,实现编程挑战的逆袭。
128 2
|
算法 调度 Python
Python高手必备!堆与优先队列的高级应用,掌握它们,技术路上畅通无阻!
【7月更文挑战第9天】Python的heapq模块实现了堆数据结构,提供O(log n)操作如`heappush`和`heappop`。堆是完全二叉树,用于优先队列,保证最大/最小元素快速访问。例如,最小堆弹出最小元素,常用于Dijkstra算法找最短路径、Huffman编码压缩数据及任务调度。通过`heappush`和`heappop`可创建和管理优先队列,如`(优先级, 数据)`元组形式。理解并运用这些概念能优化算法效率,解决复杂问题。
161 2
|
存储 算法 调度
从菜鸟到大神的蜕变之路:Python堆与优先队列,掌握它们,你就是技术圈的MVP!
【7月更文挑战第10天】在编程进阶中,Python的heapq模块提供堆(Heap)和优先队列(Priority Queue)功能,助力高效编程。堆是特殊的完全二叉树,优先队列基于堆实现,用于按优先级处理元素。
148 0
|
算法 调度 索引
Python堆与优先队列大起底:深入骨髓的解析,让你彻底告别低效编程!
【7月更文挑战第9天】Python的heapq模块实现了堆数据结构,提供heappush和heappop等操作,支持最小堆。堆是完全二叉树,满足堆属性。优先队列利用堆实现,元素按优先级出队。通过将优先级和元素打包入堆,如示例所示,能轻松处理优先级任务。掌握堆与优先队列,提升编程效率。
115 0
|
算法 安全 调度
逆天改命!Python高级数据结构堆(Heap)与优先队列,让你的算法效率飙升至宇宙级!
【7月更文挑战第8天】Python的heapq模块和queue.PriorityQueue实现了堆和优先队列,提供高效算法解决方案。堆用于Dijkstra算法求解最短路径,例如在图论问题中;PriorityQueue则在多线程下载管理中确保高优先级任务优先执行。这两个数据结构提升效率,简化代码,是编程中的强大工具。
180 0
|
安全 调度 Python
Python堆与优先队列:不只是数据结构,更是你编程路上的超级加速器!
【7月更文挑战第8天】Python的heapq模块和queue.PriorityQueue提供堆与优先队列功能。堆,作为完全二叉树,支持排序性质,heapq用于单线程操作;PriorityQueue在多线程中保证安全。通过示例展示了如何插入、删除任务,以及在多线程任务调度中的应用。堆与优先队列是高效编程的关键工具,提升代码性能与并发处理能力。
119 0
|
存储 算法 安全
解锁Python高级数据结构新姿势:堆与优先队列的实战演练,让你的代码更优雅!
【7月更文挑战第8天】Python的`heapq`模块和`queue.PriorityQueue`提供堆与优先队列功能,用于高效数据管理。堆是完全二叉树,`heapq`实现最小堆,常用于任务调度,如按优先级执行任务。当需要线程安全且更复杂操作时,`queue.PriorityQueue`成为优选,例如在管理网络请求时按优先级处理。这两个数据结构能提升代码效率和可读性。
105 0

热门文章

最新文章

  • 1
    Python零基础爬取东方财富网股票行情数据指南
    46
  • 2
    解析Python爬虫中的Cookies和Session管理
    48
  • 3
    Python日志模块配置:从print到logging的优雅升级指南
    40
  • 4
    【可视化大屏】全流程讲解用python的pyecharts库实现拖拽可视化大屏的背后原理,简单粗暴!
    40
  • 5
    (Pandas)Python做数据处理必选框架之一!(二):附带案例分析;刨析DataFrame结构和其属性;学会访问具体元素;判断元素是否存在;元素求和、求标准值、方差、去重、删除、排序...
    47
  • 6
    (Pandas)Python做数据处理必选框架之一!(一):介绍Pandas中的两个数据结构;刨析Series:如何访问数据;数据去重、取众数、总和、标准差、方差、平均值等;判断缺失值、获取索引...
    72
  • 7
    (numpy)Python做数据处理必备框架!(二):ndarray切片的使用与运算;常见的ndarray函数:平方根、正余弦、自然对数、指数、幂等运算;统计函数:方差、均值、极差;比较函数...
    42
  • 8
    (numpy)Python做数据处理必备框架!(一):认识numpy;从概念层面开始学习ndarray数组:形状、数组转置、数值范围、矩阵...
    62
  • 9
    (Python基础)新时代语言!一起学习Python吧!(四):dict字典和set类型;切片类型、列表生成式;map和reduce迭代器;filter过滤函数、sorted排序函数;lambda函数
    33
  • 10
    (Python基础)新时代语言!一起学习Python吧!(三):IF条件判断和match匹配;Python中的循环:for...in、while循环;循环操作关键字;Python函数使用方法
    54
  • 推荐镜像

    更多