C++-queue:queue基本用法【q.push(x)、q.front()、q.back()、q.pop()、q.size()、q.empty()】

这篇具有很好参考价值的文章主要介绍了C++-queue:queue基本用法【q.push(x)、q.front()、q.back()、q.pop()、q.size()、q.empty()】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

队列

一种操作受限制的线性表

一、基本概念:

  • 队列是一种线性储存数据结构,数据元素遵循“先进先出”(First in First out (FIFO))的原则
  • 添加元素在队尾(只允许添加元素)实现,删除元素在对头(只允许删除元素)实现

适用条件

排队 挂号 消息队列 广度优先搜索等符合队列特点的操作

二、队列的操作:

queue<int> q;	//以int型为例
int x;
q.empty()               如果队列为空返回true,否则返回false
q.size()                返回队列中元素的个数
q.pop()                 删除队列首元素但不返回其值
q.front()               返回队首元素的值,但不删除该元素
q.push(x)               在队尾压入新元素
q.back()                返回队列尾元素的值,但不删除该元素

三、 队列的分类;

  • 基于数组的循环队列(循环队列)
  • 基于链表的队列(链表队列)

四、基于数组的循环队列

数组存储的缺点:
入队操作:在数组的末尾添加元素,时间复杂度为O(1)
出队操作:数组头部元素出队之后,头部之后的元素均需要往前移动一个位置,时间复杂度为O(n)
循环队列
为了降低时间复杂度,将数组当作一个首尾相连的圆环,分别用两个标志front、rear代表队列的头部和尾部。删除元素时,队首标志往后移,添加元素时,若队尾没有空间,考虑数组的头部空间若还有,则在队头添加元素,防止数组内存空间的流失。
判断满或空的方法:
方法一:
设置一个标志变量flag,同时满足front=rear且flag=1时为满队列
方法二:
空一个元素,保持为空
1.空队列:队首标志与队尾重合
2.满队列:队尾标志+1=队首标志
C++实现:

#include<iostream>
using namespace std;

//队列的抽象类
template <class T>
class queue
{
public:
    virtual ~queue() {};
    virtual bool empty() const=0; 
    virtual int size() const=0;   
    virtual T& front() = 0;
    virtual void pop() = 0;
    virtual void push(const T& theElement) = 0;
};

//队列的数组类实现
template<class T>
class arrayQueue :public queue<T>
{
    arrayQueue(int initialCapacity = 10);
    ~arrayQueue() { delete[]queue; }
    bool empty()const
    {
        if (queuefront == queuerear)
            return true;
        return false;
    }
    int size() const
    {
        return (queuerear - queuefront + capacity) % capacity;
    }
    T& front()
    {
        if (queuefront == queuerear)
        {
            cout << "The queue is empty!" << endl;
            return false;
        }
        return queue[queuefront];
    }
    void pop()
    {
        if (queuefront == queuerear)
            cout << "The queue is empty!" << endl;
        queue[queuefront].~T;
        queuefront = (queuefront + 1) % capacity;
    }
    void push(const T& theElement);
private:
    int capacity;
    int queuefront;
    int queuerear;
    T* queue;
};

template<class T>
arrayQueue<T>::arrayQueue(int initialCapacity)
{
    if (initialCapacity < 1)
        cout << "InitialCapacity must >0!" << endl;
    capacity = initialCapacity;
    queue = new T[capacity];
    queuefront = 0;
    queuerear = 0;
}

template<class T>
void arrayQueue<T>::push(const T& theElement)
{
    if ((queuerear + 1) % capacity == queuefront)
    {
        T* temp = new T[2 * capacity];
        //没有形成环
        if (queuefront == 0)
            copy(queuefront, queuerear, temp);
        else
        {
            copy(queuefront, queue + capacity, temp);
            copy(queue, queuerear, temp + queue + capacity - queuefront);
        }
        queuefront = 0;
        queuerear = capacity-1;
        delete[]queue;
        queue = temp;
    }
    queue[queuerear] = theElement;
    queuerear = (queuerear + 1) % capacity;
}

五、基于链表的队列

特点
以结构体节点为单位,不存在元素移动复杂度问题以及内存的浪费问题。
链表头为队列头部,链表尾为队列尾部。
设计两个变量queueFront、queueBack记录队列的两端变化
指针queueFront为标志头指针,指针queueBack指向最后一个元素
C++实现

#include<iostream>
using namespace std;
//队列节点结构体
template<class T>
struct QueueNode
{
	T element;              //存储元素
	QueueNode<T>* next;        //记录下一个队列节点
	QueueNode(T a, QueueNode<T>* b=nullptr)
	{
		this->element = a;
		this->next = b;
	}
};
template<class T>
class ChainQueue
{
public:
	ChainQueue();
	~ChainQueue();
	bool Empty()const;
	int size() const;
	void pop();
	void push(T theElement);
	T& top();
private:
	QueueNode<T>* front;            //指向头部前一位的空指针
	QueueNode<T>* back;             //指向队列尾部的指针
	int count;
};
//队列的具体实现
template<class T>
ChainQueue<T>::ChainQueue()
{
	front = new QueueNode<T>(NULL);
	back = front;
	count = 0;
}
template<class T>
ChainQueue<T>::~ChainQueue()
{
	while (front->next!= nullptr)
	{
		QueueNode<T> *temp = front->next;
		front->next = front->next->next;
		delete temp;
	}
}
template<class T>
bool ChainQueue<T>::Empty()const
{
	if (front==back)
		return true;
	return false;
}
template<class T>
int ChainQueue<T>::size() const
{
	return count;
}
template<class T>
void ChainQueue<T>::pop()
{
	if (count == 0)
		cout << "The ChainQueue is empty!" << endl;
	QueueNode<T>* temp = front->next;
	front->next = front->next->next;
	delete temp;
	count--;
}
template<class T>
void ChainQueue<T>::push(T theElement)
{
	QueueNode<T>* temp = new QueueNode<T>(theElement);
	back->next = temp;
	back = temp;
	count++;
}
template<class T>
T& ChainQueue<T>::top()
{
	if (count == 0)
		cout<<"The ChainQueue is empty!"<<endl;
	return front->next->element;
}
int main()
{
	ChainQueue<int> cq;
	cout << "Empty?   " <<cq.Empty() <<endl;
	cq.push(10);
	cq.push(20);
	cout << "The top element is" << cq.top() << endl;
	cout << "The size is " << cq.size() << endl;
	cq.push(30);
	cq.push(40);
	cq.pop();
	cout << "The top element is" << cq.top() << endl;
	cout << "The size is " << cq.size() << endl;
	cq.pop();
	cq.pop();
	cout << "The top element is" << cq.top() << endl;
	cout << "The size is " << cq.size() << endl;
	system("pause");
	return 0;
}

C++队列_Potato_10的博客-CSDN博客_c++ 队列 

C++队列详解_T_Y_F666的博客-CSDN博客_c++ 队列文章来源地址https://www.toymoban.com/news/detail-778347.html

到了这里,关于C++-queue:queue基本用法【q.push(x)、q.front()、q.back()、q.pop()、q.size()、q.empty()】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【STL】stack、queue基本使用和模拟实现

    目录 前言 stack 接口介绍 模拟实现 queue 接口介绍 模拟实现 没有迭代器  deque介绍 stack 和 queue 本质上是一种容器配接器,就像我们平时充电时使用的电源适配器,能够将电压转换成设备能够接受的程度。 其通过封装特定容器作为其底层容器的类,通过一组特定的成员函数来

    2024年02月07日
    浏览(35)
  • 解决 Python RabbitMQ/Pika 报错:pop from an empty deque

    使用 python 的 pika 包连接rabbitmq,代码如下: 执行结果:  从结果来看,异常发生在一次长时间的消费过程(200s)完成后报错,具体为调用channel.basic_ack(delivery_tag)发生报错;推测是此时与MQ Server的连接已经被重置ConnectionResetError(104, \\\'Connection reset by peer\\\'),此时再主动确认就发生

    2024年02月13日
    浏览(46)
  • 微机原理 || push & pop 指令 (详解+例题)

    考试真的考了push和pop ,那个加减到底是什么? 考试要记:  PUSH 源    -2       字 操作(以字为单位)     例:   PUSH AL 错   必须 字 为单位   POP    源    +2       一定注意是十进制的2,注意和16进制单位转换 入栈和出栈的次序要符合后进先出原则,即: PUSH和POP一般是

    2024年02月06日
    浏览(37)
  • 一篇文章搞懂 push_back 和 emplace_back 的区别

    本来以为自己对 push_back 和 emplace_back 的理解还行,直到我室友伦伦问了一个关于 push_back 和 emplace_back 的问题。死去的 modern effective c++ 记忆又开始攻击我…因此,我痛定思痛,在阅读了大量文献之后写下本文。 (全篇 1200 字阅读大约需要 8 分钟) 撰写本文出于两点原因: 该

    2024年02月08日
    浏览(35)
  • arm push/pop/b/bl汇编指令

    目录 1. push指令 2. pop指令 3. b指令 4. bl指令 5. bx指令 1. push指令 功能描述:入栈 armv7 芯片手册: Push Multiple Registers stores multiple registers to the stack, storing to consecutive memory locations ending just below the address in SP, and updates SP to point to the start of the stored data. 语法  要点: push支持同时将

    2024年02月05日
    浏览(36)
  • Vue路由导航(replace、push、forward、back、go)

    栈的数据结构:先进后出,后进先出。 原理:push将元素压入栈内,pop将元素弹出,栈有分别有栈底指针和栈顶指针,指向栈内最低和最高的元素。 浏览器中的前进和后退的按钮也是使用了栈的数据结构实现,但也有不同。对于浏览器而言,分别有两种属性: push属性(推进

    2024年02月06日
    浏览(40)
  • ARM汇编【3】:LOAD/STORE MULTIPLE PUSH AND POP

          有时一次加载(或存储)多个值更有效。为此,我们使用LDM(加载多个)和STM(存储多个)。这些指令有一些变化,基本上只在访问初始地址的方式上有所不同。这是我们将在本节中使用的代码。我们将一步一步地研究每一条指令。         在开始之前,请记住.字指

    2024年02月11日
    浏览(36)
  • C++——Vector:push_back和emplace_back的区别,测试写入1GB大数据时的性能差距

    emplace_back是C++11引入的STL容器成员函数。emplace操作只执行构造而不执行拷贝构造。 如何理解上面这句话?先来看一个场景。 test类显式写出了三个构造函数,分别是无参构造、单参数构造、拷贝构造。因为C++中单参数的构造函数支持隐式类型转换,因此可以拿一个整型构造一

    2024年02月10日
    浏览(40)
  • js 常用函数 push()、pop()、shift()、unshift()、slice()、splice() 等

    最近对前端一些函数的用法还不是很熟悉,有一些函数容易混淆,在此总结一下,同时分享给各位小伙伴: join() 将数组中元素 组成字符串 ,需要传个参数作为连接符,不传的话默认就是逗号。 在数组 尾部逐个添加 元素,返回结果数组的长度,能接收任意数量参数,push(

    2024年02月02日
    浏览(32)
  • c++--stack,queue,priority_queue

            对于栈和队列我们是不陌生的,在数据结构阶段已经学习过,记得当时我们还是用c语言将它一步一步造出来,因为压栈与出栈正好满足数组的尾插与头删,数组的代价是及小的。对于队列是头出队列,尾插。所以就栈的实现就用的数组,队列实现就用链表。在c++中呢

    2024年01月19日
    浏览(110)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包