Python学习笔记——queue标准库(队列、栈、优先队列)、heapq标准库(堆)

queue标准库

Python自带的queue标准库可以实现队列、栈、优先队列

普通队列

import queue

q = queue.Queue()# 队列
#也可用q = queue.Queue(maxsize=5)创建有限大小的队列,用q.full()判断队满
#队满后再入队貌似会卡死,若需“顶出”另一端元素,可用双端队列
stack = queue.LifoQueue()# 栈
pq = queue.PriorityQueue()# 优先队列

================== RESTART: C:\Users\13272\Desktop\最大公约数gcd.py =================
>>> q.put(10)#10入队
>>> q.qsize()#队列大小
1
>>> q.get()#出队并返回队首元素
10
>>> q.empty()#队列是否为空
True

栈和优先队列

栈、优先队列的使用方法与队列类似,也有put()get()empty()qsize()等方法

  • 优先队列在入队时,优先将值小的元素放在队首
    对于数字、字符串等,会自动比较大小
    对于元组,优先按第一个值从小到大排,第一个值相同按第二个值从小到大排
    然而如果有更复杂的情况,可以自定义一个类,然后在类中重载__lt__“小于”成员函数,指定比较时采用的规则
  • 若需要从大到小排列,可以在入队时,将[元素的负值]入队

例如,输入整数n和n个学生的信息,按照年龄从大到小输出学生信息,若年龄相同则按姓名字典序输出

class Stu:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def __lt__(self,another):
        if self.age!=another.age:#若年龄不同,按照年龄从大到小输出
            return self.age>another.age
        return self.name<another.name#年龄相同,按照姓名从小到大输出

from queue import PriorityQueue

n = int(input())
pq = PriorityQueue()
for i in range(n):
    name,age = input().split()
    age = int(age)
    pq.put(Stu(name,age))

while pq.empty()==False:
    student = pq.get()
    print(student.name,student.age)
================= RESTART: C:/Users/13272/Desktop/优先队列输出学生名单.py ================
5
Rose 20
Tom 17
Bob 20
Eric 17
Jack 15

Bob 20
Rose 20
Eric 17
Tom 17
Jack 15

heapq标准库

heapq标准库用于实现堆

ps. PriorityQueue底层实现就是堆heapq(主要区别是,PriorityQueue提供的是面对对象的接口,而heapq只提供用于操作列表的函数更多信息)
当需要每次取出前n个大的元素,应该使用堆(提供了专门函数nlargest(n,heap)nsmallest(n,heap)),如LeetCode 1046. 最后一块石头的重量

堆(二叉堆)

  • 堆本质上是完全二叉树,由于其特性(左儿子2*i,右儿子2*i+1),直接使用数组来保存更加方便
  • 堆近似理解为优先队列,不管元素的插入顺序,总能按照元素的优先级取出元素
  • 堆的类型:
    最大堆-任意父节点的值一定大于或等于子节点(左右子节点的关系没有要求)
    最小堆-任意父节点的值一定小于或等于子节点…
  • 堆的底层实现:关键在于插入和删除时,利用[siftUp上浮和siftDown下沉]两种核心操作,始终保持最大/最小堆的性质
  • 堆的最大优势在于:在查询前n个最大/最小的元素时就有很好的性能

Python中堆的实现

  • 首先要明确,堆本质上就是列表
  • Python提供heapq标准库,用于操作具有堆性质的【列表】
    Python的heapq默认是小顶堆
创建堆、添加元素
  • 可以先创建一个空堆,然后用heappush(heap, num)将数据一个一个地添加到堆中
  • 也可以使用heapify(list)使一般的列表转化为堆
>>> from heapq import *

>>> h=[]
>>> heappush(h,4)
>>> heappush(h,7)
>>> heappush(h,3)
>>> heappush(h,2)
>>> heappush(h,8)
>>> h
[2, 3, 4, 7, 8]

>>> h=[4,7,3,2,8]
>>> heapify(h)
>>> h
[2, 4, 3, 7, 8]
删除元素

heappop(heap)只能弹出堆顶(最小值),且保证剩余的堆仍然是小顶堆

>>> heappop(h)
2
>>> h
[3, 7, 4, 8]
查询堆中前n大/小的几个元素

nlargest(n,heap)nsmallest(n,heap)

>>> nlargest(3,h)
[8, 7, 4]
>>> nsmallest(3,h)
[3, 4, 7]
合并两个有序列表

heapq.merge(list1, list2)用于将两个有序列表合并成一个新的有序列表,返回结果是一个迭代器,这个方法可以用于归并排序

>>> l1=[1,5,8]
>>> l2=[2,3,9]
>>> list(merge(l1,l2))
[1, 2, 3, 5, 8, 9]
  • 3
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值