python 堆和优先队列的使用详解

Python堆和优先队列的使用详解

什么是堆和优先队列

在计算机科学中,优先队列是指每个元素都被赋予了一个优先级。当元素要被处理时,具有最高优先级的元素先被处理。优先队列可以用各种方式实现,但是在Python中,我们通常使用heapq模块中的堆来实现优先队列。

堆(Heap)

堆是一种特殊的数据结构,它是一种完全二叉树,它满足堆属性:在最小堆中,父节点的值始终小于或等于其子节点的值;在最大堆中,父节点的值始终大于或等于其子节点的值。

在Python中,我们可以使用heapq模块来创建和操作堆结构。heapq模块的一些常用函数包括:

  • heappush(heap, x):将x压入堆heap中
  • heappop(heap):从堆heap中弹出并返回最小的元素
  • heapify(heap):将heap列表转换为堆

优先队列

优先队列是一个元素带有优先级的队列。当元素被插入队列中时,具有较高优先级的元素将被先出队列。在Python中,我们可以使用heapq模块来创建和操作优先队列。

例如,我们可以使用如下代码来创建一个优先队列:

import heapq

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]

这个例子中,我们使用一个堆来实现优先队列。我们使用一个三元组来表示元素,其中第一个元素是其优先级(负数用于实现最大堆),第二个元素是一个索引(用于确保元素添加到队列中的顺序),第三个元素是元素本身。

示例

示例1:使用堆排序一个列表

import heapq

def heap_sort(nums):
    heap = []
    for num in nums:
        heapq.heappush(heap, num)
    sorted_nums = []
    while heap:
        sorted_nums.append(heapq.heappop(heap))
    return sorted_nums

nums = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
print(heap_sort(nums))

这个示例展示了如何使用heapq模块来实现堆排序。我们首先将要排序的序列中的元素添加到一个空堆中,然后弹出并追加堆中的最小元素,直到堆为空为止。

运行结果:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

示例2:使用优先队列解决赛车比赛的问题

假设比赛中有N辆赛车,第i辆赛车有一个初始时间S[i],需要在比赛中用最短的时间到达终点。每辆赛车每秒钟可以到达一个相邻的位置,也可以等待一个时间单位。如果一辆赛车在某个时间单位inner起跑并到达终点,则这辆赛车的得分为arrivalTime-inner,其中arrivalTime表示这辆赛车到达终点的时间,inner表示这辆赛车起跑的时间。

我们的目标是为第i辆赛车计算一个最小的inner,使得这辆赛车的得分最高。我们可以使用一个优先队列来解决这个问题。

import heapq

def calc_optimal_lap_times(S):
    N = len(S)
    pq = []
    for i in range(N):
        heapq.heappush(pq, (S[i], i, S[i], 1))
    ans = [None] * N
    while pq:
        _, cur_idx, cur_time, laps = heapq.heappop(pq)
        if ans[cur_idx] is not None:
            continue
        ans[cur_idx] = cur_time - S[cur_idx] + laps * (N - cur_time)
        for i in range(N):
            if ans[i] is None:
                heapq.heappush(pq, (cur_time + abs(i - cur_idx), i, cur_time + abs(i - cur_idx), laps + 1))
    return ans

S = [3, 1, 5, 4, 2]
print(calc_optimal_lap_times(S))

这个示例展示了如何使用优先队列解决赛车比赛的问题。我们使用一个堆来实现优先队列,其中每个元素是一个四元组,表示赛车的当前时间、索引、总时间和已经完成的圈数。我们从每个赛车的起始时间开始,不断弹出最高优先级的元素,然后将其向前移动一秒,并将新元素插入优先队列中,直到我们已经计算了每辆赛车的最优时间。

运行结果:

[9, 3, 12, 11, 6]

这个结果告诉我们,第一辆赛车应该在第9秒出发,第二辆赛车在第3秒出发,以此类推。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python 堆和优先队列的使用详解 - Python技术站

(0)
上一篇 2023年5月14日
下一篇 2023年5月14日

相关文章

  • python redis连接 有序集合去重的代码

    Python是一种高级语言,具有简单易读、易学习、易上手快等特点,且开发效率高,广泛应用于数据处理、Web开发、机器学习等领域的应用。而Redis则是一个高性能的键值对存储系统,具有高效、稳定、可靠等特点,被广泛用于分布式、缓存、消息队列等场景。 Python中用于连接Redis的模块主要是redis-py,这个模块提供了方便的Redis访问方法,可轻松使用…

    python 2023年5月14日
    00
  • python读写文件操作示例程序

    下面是“python读写文件操作示例程序”的完整攻略: 1. 读取文件内容 首先,我们需要确定要读取的文件路径。接下来,可以使用Python内置的open()函数来打开该文件,并使用read()函数读取其中的内容。下面是对应的示例代码: # 打开文件 file = open(‘filename.txt’, ‘r’) # 读取文件内容 content = fi…

    python 2023年5月30日
    00
  • Python实现的弹球小游戏示例

    下面是详细讲解“Python实现的弹球小游戏示例”的完整攻略。 简介 这是一个使用Python编写的小游戏示例,玩家可以通过控制球拍反弹小球,使小球不落下来,从而获得分数。 游戏规则 游戏开始时,小球在屏幕随机位置弹出,并向随机方向移动。 玩家通过控制球拍左右移动来接住小球,防止小球落到屏幕底部。 如果小球与球拍接触,球会反弹,并根据接触点的位置改变运动方向…

    python 2023年5月19日
    00
  • 使用python实现knn算法

    使用Python实现KNN算法可以分为以下几个步骤: 数据预处理 KNN算法要求数据必须是数值类型,因此需要将非数值类型的数据转换为数值型。此外,还需要对数据进行标准化处理,将不同范围的特征值转换为同等重要性的数值。常用的方法是z-score标准化或min-max缩放。 示例说明: import pandas as pd from sklearn impor…

    python 2023年6月3日
    00
  • Python 3.10 的首个 PEP 诞生,内置类型 zip() 迎来新特性(推荐)

    让我来为您详细讲解一下 “Python 3.10 的首个 PEP 诞生,内置类型 zip() 迎来新特性(推荐)” 的完整攻略。 Python 3.10 的首个 PEP 诞生 PEP(Python Enhancement Proposal)是 Python 社区用于提出 Python 语言新特性和改进的文档形式。在最新的 Python 3.10 版本中,它的…

    python 2023年6月3日
    00
  • python定时任务schedule库用法详细讲解

    下面是详细讲解“python定时任务schedule库用法详细讲解”的攻略: 1. 简介 Python的schedule库是一种定时任务库,可以让我们方便地在Python中执行周期性的任务。它可以替代Python自带的time.sleep()方法,因为它不会阻塞主线程。 2. 安装 在使用之前,需要安装schedule库。可以使用pip命令安装: pip i…

    python 2023年5月18日
    00
  • python 多进程和多线程使用详解

    Python 多进程和多线程使用详解 Python 作为一门高级语言,在并发编程方面拥有很好的支持。在多进程和多线程方面,Python 同样提供了丰富的标准库支持。在本文中,我们将详细讲解并发编程中的多进程和多线程的使用。 多进程 基本概念 多进程是指在一个程序中同时运行多个并发执行的任务,每个任务拥有独立的进程空间。在 Python 中,我们可以通过创建多…

    python 2023年5月18日
    00
  • python目标检测SSD算法预测部分源码详解

    下面是详细讲解“python目标检测SSD算法预测部分源码详解”的完整攻略,包含两个示例说明。 python目标检测SSD算法预测部分源码详解 SSD(Single Shot MultiBox Detector是一种目标检测算法,它可以在一张图像中同时检测多个目标。在SSD算法中,预测部分非常重要的一部分,它可以根据输入图像预测出目标的位置和类别。下面是SS…

    python 2023年5月14日
    00
合作推广
合作推广
分享本页
返回顶部