• Python数据结构2-----队列和堆


    一、线性结构:栈、队列、双端队列、列表

    二、非线性结构:树、图、堆

    【算法中看堆是非线性的,因为其相当于完全二叉树,但堆的存储元素是采用线性的顺序表数组来实现的】

    三、队列:

    1、队列类型:FIFO、LIFO、双端队列、循环队列

    FIFO:先进先出

    LIFO:后进先出(相当于栈)

    双端队列:LIFO和FIFO的结合,就是可从队首和队尾添加和删除元素。

    循环队列:队首和队尾相连(可以解决假溢出)

    2、FIFO【先进先出】、LIFO【后进先出】

    Python自带的Queue模块(import queue【python3】、import Queue【Python2】)【线程不安全,需加锁】

      有三种队列类型:FIFO(queue.queue)、LIFO(queue.LifoQueue)、优先级队列(queue.PriorityQueue)【优先级队列越低越先出来】【堆】

    FIFO:import queue

    创建一个队列长度为10的对象:q=queue.queue(maxsize=10)

    队尾插入数据x:q.put(x)

    队首删除数据:q.get(),并返回该数据

    返回队列的大小:q.qsize()

    判断队列是否为空:q.empty(),若为空则返回True,反之则FALSE

    判断是否为满:q.full与maxsize相呼应

    3、Python自带的双端队列Deque模块(from collections import deque) 【线程安全,因为GIL】

    (1)新建一个deque对象:q=deque('abcdefgh'),或者创建一个大小为5的队列q=deque(5)

    (1)q.appendleft(x):在列表左侧插入【O(1)】

    (2)q.popleft():弹出列表左侧的值【O(1)】

    (3)extendleft:在左侧扩展【O(k)】

    (4)q.append(x):在列表右侧插入【O(1)】

    (5)q.pop():弹出列表右侧的值【O(1)】

    (6)extend:在右侧扩展【O(k)】

    (7)q.rotate(-n):将左端的n个元素移动到右端【O(k)】

      q.rotate(n):将右端的n个元素移动到左端

      q=deque('abcdef')

      q.rotate(-2)

      print(q)//deque(['c','d','e','f','a','b'])
      q.rotate(2)

      print(q)//deque(['e','f','a','b','c','d'])

    (8)q.remove('c'):删除一个指定元素【O(n)】

    (9)q.clear():清空链表所有元素,使其长度为0

    (10)q.reverse():将队列反转

    (11)q.count(x):返回q中x的数量

    (12)len(q):返回q的长度

    4、Python实现循环队列:

    队尾出来进队首,双端队列的rotate可以实现循环队列。

    下面的例子是用queue中的FIFO实现一个功能,6个人传土豆,每数到7就淘汰手中有土豆的人,直到最后只剩一个人。

    #循环队列,num一定要比人数多
    import queue
    def hotpotato(namelist,num):
        que=queue.Queue(len(namelist))
        for name in namelist:
            que.put(name)
        while que.qsize()>1:
            for item in range(num):
                que.put(que.get())
            que.get()
        return que.get()
    
    
    
    namelist=['a','b','c','d','e','f']
    print(hotpotato(namelist,7))

     5、列表、queue、deque都可以用作队列,他们的比较:

    list缺点:插入队尾时需要用insert(0,x),【因为队首在队尾】,别的元素要往后移,时间复杂度大】

    queue的缺点:queue只能做put,put方向只能在队尾。

    deque的缺点:remove(x) 和获取索引时速度慢,因为需要执行多个数据块。list相对快一点。

    四、堆:【是一棵完全二叉树】

    1、python自带的堆模块:import heapq【实现最小堆】

    【实现最大堆:将元素取反存入堆,取出时再取反:将push(e)改为push(-e)、pop(e)改为-pop(e)。】

    • heap = [] #创建了一个空堆
    • heapq.heappush ( heap,item ) #往堆heap中插入一条新的值item
    • heapq.heapify(listx) #以线性时间将一个列表转化成堆
    • item = heapq.heappop ( heap ) # 从堆中弹出最小值
    • item = heap [0] #查看堆中最小值,不弹出
    • item = heapq.heapreplace(heap,item) #弹出并返回最小值,然后将heapreplace方法中item的值插入到堆中,堆的整体结构不会发生改变。这里需要考虑到的情况就是如果弹出的值大于item的时候我们可能就需要添加条件来满足function的要求:
      • if item > heap[0]:    item = heapreplace(heap, item)
    • heapq.heappushpop() #顾名思义,将值插入到堆中同时弹出堆中的最小值。 
    • merge(heap1,heap2,heap3) #合并多个堆然后输出
    • heapq.nlargest(n , heap, key=None) #从堆中找出做大的N个数,key的作用和sorted( )方法里面的key类似,用列表元素的某个属性和函数作为关键字。
    • heapq.nsmallest(n, iterable, key=None) #找到堆中最小的N个数用法同上。
  • 相关阅读:
    Android studio 使用flutter插件 运行第一个flutter项目 报错 Warning: License for package Android SDK Build-Tools 28.0.3 not accepted.
    Android 使用GPS获取到经纬度后 无法在Android8.0上使用Geocoder类获取位置信息
    Android 利用 gson 将 json 转成 对象object 集合list
    Android 6.0 7.0 8.0 一个简单的app内更新版本-okgo app版本更新
    iview组件 eslint校验出错 Parsing error: x-invalid-end-tag
    新建 Vue项目 使用iView报错解决
    Typora 自定义主题 修改左右间距
    Vue 嵌套数组 数组更新视图不更新
    如何在手机设备上实时调试
    通过ReRes让chrome拥有路径映射的autoResponse功能。
  • 原文地址:https://www.cnblogs.com/Lee-yl/p/8955328.html
Copyright © 2020-2023  润新知