Python进阶学习(9)—队列,双端队列以及队列堵塞

队列

队列这个概念非常好理解。你可以把它想象成排队买票,先来的先买,后来的人只能站末尾,不允许插队。先进者先出(FIFO),这就是典型的“队列”。

我们知道,栈只支持两个基本操作:入栈 push()和出栈 pop()。队列跟栈非常相似,支持的操作也很有限,最基本的操作也是两个:入队 enqueue(),放一个数据到队列尾部;出队 dequeue(),从队列头部取一个元素。
在这里插入图片描述
所以,队列跟栈一样,也是一种操作受限的线性表数据结构。
队列的概念很好理解,基本操作也很容易掌握。作为一种非常基础的数据结构,队列的应用也非常广泛,特别是一些具有某些额外特性的队列,比如循环队列、阻塞队列、并发队列。它们在很多偏底层系统、框架、中间件的开发中,起着关键性的作用。

1.1 队列的抽象数据类型

Q.dequeue():从队列中移除并返回第一个元素,如果队列为空,则触发一个错误。
Q.dequeue(e):给队尾添加一个元素e
队列的抽象数据类型(ADT)
支持如下方法(类似于堆栈的pop方法):
Q.first():在不移除的前提下返回队列的第一个元素;如果队列为空,则触发一个错误
Q.is_empty():如果队列Q没有包含任何元素则返回”True“
len(Q):返回队列的长度,在Python中,我们通过__len__这个特殊方法实现。

1.2 Python队列的实现方法

class Empty(Exception):
    pass

class ArrayQueue(object):
    def __init__(self):
        ''' '''
        self._data = []
    def enqueue(self,e):
        '''向队尾添加元素'''
        self._data.append(e)

    def dequeue(self):
        '''从队列中移除并返回第一个元素,如果队列为空,则触发一个错误'''
        if self.is_empty():
            raise Empty('Queue is empty')
        else:
            return self._data.pop()
    def first(self):
        '''在不移除的前提下返回队列的第一个元素;如果队列为空,则触发一个错误 '''
        if self.is_empty():
            raise Empty('Queue is empty')
        else:
            return self._data[0]

    def is_empty(self):
        '''如果队列Q没有包含任何元素则返回”True“'''
        return len(self._data) == 0

    def __len__(self):
        '''返回队列的长度,在Python中,我们通过__len__这个特殊方法实现。'''
        return len(self._data)

也可以写成

class Empty(Exception):
    pass

class New_ArreyQueue(object):
    Queue_LONG = 10
    def __init__(self):
        self._data = [None] * New_ArreyQueue.Queue_LONG
        self._size = 0
        self._front = 0

    def __len__(self):
        for k in self._data:
            if k != None:
                self._size +=1
        return self._size

    def is_empty(self):
        return self._size == 0

    def first(self):
        if self.is_empty():
            raise Empty('Queue is empty')
        return self._data(self._front)

    def dequeue(self):
        if self.is_empty():
            raise Empty('Queue is empty')
        answer = self._data[self._front]
        self._data[self._front] = None
        self._front = (self._front +1) % len(self._data) # 第一个元素的索引
        self._size -= 1
        return answer

    def enqueue(self,e):
        if self._size == len(self._data):
            self._resize(2 * len(self._data))
        avail = (self._front + self._size) % len(self._data) # 求出最后一个数值的索引
        self._data[avail] = e
        self._size += 1

    def _resize(self,cap):
        old = self._data
        self._data = [None] *cap
        walk = self._front
        for k in range(self._size):
            self._data[k] = old[walk]
            walk = (walk + 1) % len(old)
        self._front = 0

1.3 双端队列

双端队列(deque,全名double-ended queue),是一种具有队列和栈的性质的数据结构。
双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行。双端队列可以在队列任意一端入队和出队。
在这里插入图片描述

1.4双端队列的抽象数据类型

ArrayDeque() 创建一个空的双端队列
D.add_first(item) 给队头加入一个item元素
D.add_last(item) 从队尾加入一个item元素
D.delete_first()从队列中删除并返回第一个元素,如果队列为空,则触发一个错误。
D.delete_last() 从队列中删除并返回最后一个元素,如果队列为空,则触发一个错误。
D.is_empty() 判断双端队列是否为空
len(D):返回队列中的元素个数,在Python中,我们使用__len__这个特殊方法实现
D.first():从队列返回(但不删除)第一个元素,如果队列为空,则触发一个错误。
D.last(): 从队列返回(但不删除)最后一个元素,如果队列为空,则触发一个错误。

1.5 Python队列的实现方法

class Empty(Exception):
    pass

class ArrayDeque(object):
    def __init__(self):
        self._data = []

    def add_first(self,item):
        '''从队头加入一个item元素'''
        self._data.insert(0,item)

    def add_last(self,item):
        '''从队尾加入一个item元素'''
        self._data.append(item)

    def delete_first(self):
        '''从队列中删除并返回第一个元素,如果队列为空,则触发一个错误。'''
        if self.is_empty():
            raise Empty('Queue is empty')
        return self._data.pop(0)

    def delete_last(self):
        '''从队列中删除并返回最后一个元素,如果队列为空,则触发一个错误。'''
        if self.is_empty():
            raise Empty('Queue is empty')
        return self._data.pop()

    def is_empty(self):
        '''判断双端队列是否为空'''
        return len(self._data) == 0

    def __len__(self):
        '''返回队列中的元素个数,在Python中,我们使用__len__这个特殊方法实现'''
        if self.is_empty():
            raise Empty('Queue is empty')
        return len(self._data)

    def first(self):
        '''从队列返回(但不删除)第一个元素,如果队列为空,则触发一个错误。'''
        if self.is_empty():
            raise Empty('Queue is empty')
        return self._data[0]

    def last(self):
       '''从队列返回(但不删除)最后一个元素,如果队列为空,则触发一个错误'''
       if self.is_empty():
           raise Empty('Queue is empty')
       return self._data[-1]
1.6 阻塞队列

阻塞队列其实就是在队列基础上增加了阻塞操作。简单来说,就是在队列为空的时候,从队头取数据会被阻塞。因为此时还没有数据可取,直到队列中有了数据才能返回;如果队列已经满了,那么插入数据的操作就会被阻塞,直到队列中有空闲位置后再插入数据,然后再返回。

案例
我们知道,CPU 资源是有限的,任务的处理速度与线程个数并不是线性正相关。相反,过多的线程反而会导致 CPU 频繁切换,处理性能下降。所以,线程池的大小一般都是综合考虑要处理任务的特点和硬件环境,来事先设置的。

当我们向固定大小的线程池中请求一个线程时,如果线程池中没有空闲资源了,这个时候线程池如何处理这个请求?是拒绝请求还是排队请求?各种处理策略又是怎么实现的呢?

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值