一、概述

队列(queue): 只允许在一端进行插入 (队尾) 操作,而在另一端 (队头) 进行删除操作的线性表。
队头:删除操作的一端——front
队尾:插入操作的一端——rear

特点:先进先出(First In First Out)

其他常用队列:循环队列、阻塞队列、并发队列。

二、队列的抽象数据类型

ADT 队列 (Queue)
Data同线性表。元素具有相同的类型,相邻元素具有前驱和后继关系
OpreationInitQueue(*Q):                初始化操作,建立一个空队列Q。DestroyQueue(*Q):             若队列Q存在,则销毁它。ClearQueue(*Q):               将队列Q清空。QueueEmpty(Q):                若队列为空,返回true,否则返回false。GetHead(Q,*e):                若队列Q存在且非空

二、C++队列的方法

  1. back()——返回最后一个元素;
  2. empty()——如果队列空则返回true,否则返回false;
  3. front()——返回第一个元素;
  4. pop()——从队头删除第一个元素;
  5. push()——在队尾插入一个元素;
  6. size()——返回队列中元素的大小;
#include<iostream>
#include<queue>
using namespace std;int main()
{queue<int> que;// 入队for(int i = 0; i < 50; i++){que.push(i);}cout<<"the size of queue:"<<que.size()<<endl;while(!que.empty()){cout<<"the front element of queue:"<<que.front()<<"    ";cout<<"the rear element of queue:"<<que.back()<<endl;que.pop();}cout<<"the size of queue:"<<que.size()<<endl;return 0;
}

三、实现

1、顺序队列——数组实现

  • 顺序队列需事先确定队列的大小,不支持动态分配存储空间,所以插入和删除元素比较省时,但是会造成空间的浪费。

解决方法:循环队列 =》解决空间浪费的问题
循环队列的实现:

#include <iostream>
using namespace std;const int MAXSIZE = 1000;
typedef int ELEMTYPE;
const int N = 10;
typedef struct{ELEMTYPE data[MAXSIZE];int head;   /*队头指针*/int rear;   /*队尾指针*/
}Queue;Queue Q;
void initQueue(Queue &Q);
void printQueue(Queue &Q);
bool isQueueEmpty(Queue &Q);
bool isQueueFull(Queue &Q);
bool EnQueue(Queue &Q, ELEMTYPE e);
bool DeQueue(Queue &Q, ELEMTYPE &e);int main()
{for(int i = 0; i < N; i++){EnQueue(Q, i);}printQueue(Q);return 0;
}void initQueue(Queue &Q)
{Q.head = 0;Q.rear = 0;
}
void printQueue(Queue &Q)
{ELEMTYPE e;while(!isQueueEmpty(Q)){DeQueue(Q,e);cout<<e<<" ";}cout<<endl;
}
bool isQueueEmpty(Queue &Q)
{if(Q.head == Q.rear)return true;elsereturn false;
}
bool isQueueFull(Queue &Q)
{if((Q.rear+1)%MAXSIZE == Q.head)return true;elsereturn false;
}
bool EnQueue(Queue &Q, ELEMTYPE e)
{if(isQueueFull(Q))return false;Q.rear = (Q.rear+1)%MAXSIZE;Q.data[Q.rear] = e;return true;
}
bool DeQueue(Queue &Q, ELEMTYPE &e)
{if(isQueueEmpty(Q))return false;Q.head = (Q.head+1)%MAXSIZE;e = Q.data[Q.head];return true;
}

2、链式队列——链表实现

  • 可以不需要事先知道队列的大小,支持动态和释放空间,但是插入和删除操作比较耗时
#include <iostream>
using namespace std;
struct NODE//双向链表基本单元结构
{int data;NODE *next;//后继指针NODE *pre;//前驱指针
};
class QUEUE//定义queue类封装数据和实现
{private:NODE *front;//队头指针NODE *tail;//队尾指针unsigned size;
public:QUEUE();~QUEUE(){};void initialize();  //初始化void enqueue(int n); //入队void dequeue();  //出队int get_front();  //获取元素void clear();  //清空队列int get_size();  //返回元素个数bool isempty();  //判断是否为空void display_queue(); //输出队列
};
QUEUE::QUEUE()
{initialize();
}
void QUEUE::initialize()
{//初始化头部和尾部指针front = new NODE();tail = new NODE();//将头尾连接front->data = tail->data = 0;front->pre = tail->next = NULL;front->next = tail;tail->pre = front;size = 0;  //设置元素个数为0
}
void QUEUE::enqueue(int n)
{//开辟新节点NODE *new_ele = new NODE();//设置数据new_ele->data = n; //将新节点插入到双向链表尾部tail->pre->next = new_ele; new_ele->next = tail;new_ele->pre = tail->pre;tail->pre = new_ele;size++;  //元素个数加1
}
void QUEUE::dequeue()
{if (isempty())//避开对空队列的操作{cout << "queue is empty" << endl; return;}//获取删除将要删除的元素指针NODE *temp = front->next;front->next = temp->next;temp->next->pre = front; delete(temp);//释放内存size--;
}
int QUEUE::get_front()
{if (front->next != tail)return front->next->data;elsecout << "empty queque" << endl;return -1;
}
void QUEUE::clear()
{NODE *temp = front;//遍历链表释放所有节点内存 while(temp != tail){NODE *del_data = temp;temp = temp->next;delete(del_data);}//调用函数重新初始化initialize();
}
int QUEUE::get_size()
{return size;
}
void QUEUE::display_queue()
{NODE *temp = front->next;while (temp != tail){cout << temp->data << " ";temp = temp->next;}if (isempty())cout << "queue is empty" << endl;elsecout << endl;
}
bool QUEUE::isempty()
{return front->next == tail;
}
int main(int argc, char const *argv[])
{QUEUE que; /*     *do somthing here     */    return 0;
}

3、循环队列

  • 关键:判断队列是空对还是满队

    • 空:head == tail
    • 满:(tail+1)%n == head
  • 当循环队列满队时,tail指针指向的位置实际并没有存储数据。=》循环队列会浪费一个数组的存储空间
 template<class T>class SeqQueue{protected:T *element;int front,rear;int maxSize;public:SeqQueue(int sz=10){front=rear=0;maxSize=sz;element=new T[maxSize];}~SeqQueue(){delete[] element;}bool EnQueue(const T& x){//入队 if(isFull()) return false;element[rear]=x;rear=(rear+1)%maxSize;return true;}bool DeQueue(T& x){//出队 if(isEmpty()) return false;x=element[front];front=(front+1)%maxSize;return true;}bool getFront(T& x){//获取队首元素 if(isEmpty()) return false;x=element[front];return true;}void makeEmpty(){//队列置空 front=rear=0;}bool isEmpty()const{//判断队列是否为空 return (rear==front)?true:false;}bool isFull()const{//队列是否为满return ((rear+1)%maxSize==front)?true:false;}int getSize()const{return (rear-front+maxSize)%maxSize;}}; 

4、阻塞队列

支持阻塞操作的队列。具体来讲,支持阻塞添加和阻塞移除。

阻塞添加: 当队列满的时候,队列会阻塞插入插入的元素的线程,直到队列不满;
阻塞移除: 在队列为空时,队里会阻塞插入元素的线程,直到队列不满。

阻塞队列常用于“生产者-消费者模型”,生产者是向队列添加元素的线程;消费者是从队列取元素的线程。

5、并发队列

并发队列就是队列的操作多线程安全。
实现:基于数组的循环队列,利用CAS原子操作,可以实现非常高效的并发队列

五、队列(Queue)相关推荐

  1. python 多进程multiprocessing 队列queue报错:AttributeError: Can't pickle local object

    今天,test-191204-单个摄像头调用multiprocessing线程队列queue识别时,报错: D:\20191031_tensorflow_yolov3\python\python.ex ...

  2. Windows Azure Service Bus (3) 队列(Queue) 使用VS2013开发Service Bus Queue

    <Windows Azure Platform 系列文章目录> 在之前的Azure Service Bus中,我们已经介绍了Service Bus 队列(Queue)的基本概念. 在本章中 ...

  3. Python 线程队列 Queue – FIFO - Python零基础入门教程

    目录 一.Python 线程队列分类 二.Python 线程先进先出队列 Queue 简介 三.Python 线程先进先出队列 Queue 常用函数 四.Python 线程先进先出队列 Queue 使 ...

  4. 递归泛型二叉树、List、Set、Map、队列Queue

    一. 二叉树递归泛型版 泛型比较大小转成Comparable调用compareTo 将泛型值t强转Comparabl,调用compareTo用来比较public class Treetwo2<T ...

  5. java数据结构——6队列(Queue)

    六.队列(Queue) 在"队列"(Queue)这种数据结构中,数据项是先进先出(FIFO:first in first out).队列的容量可以有限,也可以是无限的. 1.基于数 ...

  6. python queue put阻塞_python 队列(queue)阻塞

    背景:python 队列 queue.Queue 或 multiprcessing.Queue 或其他队列在写入队列或从队列中读取元素时,都有可能会发生线程阻塞. 下面来说一下阻塞的类型,然后怎么避免 ...

  7. 【数据结构与算法】程序内功篇五--队列

    程序内功篇五--队列 一.队列 1.队列原理 2.队列演示 二.顺序队列 >1.顺序队列原理 >2.顺序队列的创建 >3.顺序队列的入队 >4.顺序队列的出队 >5.顺序 ...

  8. python队列queue不堵塞_python 队列(queue)阻塞

    背景:python 队列 queue.Queue 或 multiprcessing.Queue 或其他队列在写入队列或从队列中读取元素时,都有可能会发生线程阻塞. 下面来说一下阻塞的类型,然后怎么避免 ...

  9. python队列线程池_实例详解:python高级编程之消息队列(Queue)与进程池(Pool)

    今天为大家带来的内容是:python高级编程之消息队列(Queue)与进程池(Pool),结合了实例的形式详细分析了Python消息队列与进程池的相关原理.使用技巧与操作注意事项!!! Queue消息 ...

  10. PYTHON——多线程:队列Queue数据结构

    1.队列模块简介 队列是一种数据结构,用于存放数据,类似列表.它是先进先出模式(FIFO模式),类似管道一般: 单线程不需要用到队列Queue,它主要用在多线程之间的,Queue称为多线程利器. 列表 ...

最新文章

  1. spring servlet 扩展undertow
  2. zabbix 监控 Esxi
  3. book电子书数据库设计_如何为杀手book的封面设计写出完美的摘要
  4. 接口中的默认方法和静态方法
  5. 电脑显示连接了网络但是不能上网_为什么电脑插上网线显示已连接却上不了网...
  6. java 基础做增删改查教学_Java Mybatis 增删改查 简单使用 入门 简版
  7. L323 英语有必要学语法吗
  8. js学习总结----深入扩展-js同步与异步编程
  9. 用大白话带你理解CPU指令集
  10. ubuntu18安装tim
  11. ENVI5.3.1高分2号影像预处理流程
  12. python处理excel教程视频-从零基础开始用Python处理Excel数据 视频教程
  13. 金丹期前期:1.2、python语言-python的基本元素:变量及命名规则、数据类型及转换、运算符、输入输出
  14. 麦客服务器维修,麦客
  15. 黄柳青:中国软件的致命缺陷是什么!
  16. 2022年4月蓝桥杯软件类省赛:真题+解析
  17. Struts2的学习 主要是知识点和基础知识
  18. Win10自带邮件系统绑定腾讯企业邮箱
  19. Linux中lvdisplay命令的用法,lvdisplay
  20. ARCore之路:ARCore 中的 Session Config 配置中的参数介绍

热门文章

  1. 在java中读取某个文件中的数据内容
  2. Java设计模式-代理模式 理论代码相结合
  3. c调用按钮点击事件_React中事件的写法总结
  4. Acronis True Image无法卸载或者卸载导致无法开机解决办法
  5. python打地鼠游戏代码100行_PythonStudy_打地鼠游戏代码
  6. python中如何调用类_python如何调用java类
  7. 成功解决slave无datanode问题
  8. Logistic回归的自己推导
  9. android include 点击事件,Android 多个include标签的监听事件处理
  10. 数学实验matlab课后习题答案,matlab数学实验教程答案