数据结构--队列

具有先进先出的特性,只支持入队和出队操作的数据结构
  • 顺序队列,链式队列,循环队列,阻塞队列和并发队列
顺序队列
  • 需要一个head指向队头的指针和tail指向队尾的指针,随着不停地进行入队、出队操作,head 和 tail 都会持续往后移动
  • 队满的判断条件是 tail == n,队空的判断条件是head == tail
    在这里插入图片描述
  • 当 tail 移动到最右边,即使数组中还有空闲空间(数据的删除导致数组数据不连续),也无法添加数据了。这个缺陷用数据搬移操作来解决。每次出队相当于删除数组下标0的数据,要搬移整个队列中的数据,这样出队的时间复杂度从O(1)变成O(n)。
    • 优化:实际出队不用搬移数据,如果没有空闲,只需要在入队时,再触发一次数据数据搬移操作
    • 当队列的 tail 指针移动到数组的最右边后,如果有新的数据入队,我们可以将 head 到 tail 之间的数据,整体搬.移到数组中 0 到 tail-head 的位置。
      在这里插入图片描述
  • 时间复杂度:出队O(1),入队O(n)
链式队列
  • 同样需要2个指针,入队时,tail->next= new_node, tail = tail->next;出队时,head =head->next。
    在这里插入图片描述
循环队列
  • 优势:在数组模拟队列时候,在 tail==n 时,会有数据搬移操作,入队操作性将低到O(n)。
  • 缺点:当队列满时,图中的 tail 指向的位置实际上是没有存储数据,所以,循环队列会浪费一个数组的存储空间。
    在这里插入图片描述
  • 队满的判空条件:(tail+1)%n=head
阻塞队列
  • 运用广泛
  • 增加了阻塞操作。当队列为空,从队头取数据会被阻塞,直到有数据才能返回;如果队列已满,插入操作就会被阻塞,直到队列有空的位置。
  • 是一个“生产者-消费者模型”,有效的协调生产和消费的速度。在这里插入图片描述
并发队列
  • 在多线程情况下,会有多个线程同时操作队列,这个时候就会存在线程安全问题,线程安全的队列的就是并发队列,实现方式就是在入队和出队方法上加锁,但锁粒度大并发度会比较低,同一时刻仅允许一个存活着取操作。在循环队列,利用CAS原子操作,可以实现非常高效的并发控制。
当我们向固定大小的线程池中请求一个线程时,线程池没有空闲线程时,新的任务请求线程资源时,线程池该如何处理?各种处理策略又是如何实现的呢?
  • 第一种是非阻塞处理,直接拒绝任务请求;第二种是阻塞处理,将请求排队,当有空闲线程,取出排队的请求继续处理
  • 存储排队请求:先进先出
  • 基于链表实现方式,可以实现一个支持无线排队的无界队列,但是可能导致过多的排队请求,响应时间长,所以给予链表实现的无限队列的线程池是不合适的
  • 数组实现的有界队列,当线程池中排队的请求超过队列大小,接下来的请求会被拒绝,需要设置一个合理的队列大小。
  • 实际中,当没有空闲资源时,基本上都可以通过队列实现请求排队
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值