【C++初阶】queue的常见操作和模拟实现

在这里插入图片描述

个人主页:@Weraphael
✍作者简介:目前学习C++和算法
✈️专栏:C++航路
希望大家多多支持,咱一起进步!
如果文章对你有帮助的话
欢迎 评论 点赞 收藏 加关注✨


目录

  • 一、queue的基本概念
  • 二、 queue的常见操作
      • 2.1 构造函数
      • 2.2 empty
      • 2.3 size
      • 2.4 front
      • 2.5 back
      • 2.6 push
      • 2.7 pop
      • 2.8 赋值操作
  • 三、有关队列的力扣经典题
      • 3.1 二叉树的层序遍历
      • 3.2 用队列实现栈
  • 四、模拟实现queue
      • 4.1 简介
      • 4.2 代码实现

一、queue的基本概念

  • queue是一种容器适配器,也是一种先进先出(First in First Out,简称FIFO)的数据结构, 其中从容器一端插入元素,另一端提取元素
  • 容器适配器通常会限制对底层容器的访问方式,因此不能遍历,但队列中只有

【C++初阶】queue的常见操作和模拟实现_第1张图片

二、 queue的常见操作

2.1 构造函数

  • 默认构造
// T可以是任意类型
queue<T> q;
  • 拷贝构造
//q已知
queue<T> qq(q);

2.2 empty

功能:检测队列是否为空,是返回true,否则返回false

2.3 size

功能:返回队列中有效元素的个数

2.4 front

功能:返回队头元素

2.5 back

功能:返回队尾元素

2.6 push

功能:在队尾将元素val入队列

2.7 pop

功能:将队头元素出队列

2.8 赋值操作

#include 
#include 
using namespace std;

int main()
{
	queue<int> q;
	// 插入
	q.push(10);
	q.push(20);
	q.push(30);
	q.push(40);


	queue<int> qq;
	//赋值运算符
	qq = q;

	cout << "元素个数:" << qq.size() << endl;
	cout << "队头元素" << qq.front() << endl;
	cout << "队尾元素" << qq.back() << endl;

	// 遍历
	while (!qq.empty())
	{
		cout << qq.front() << ' ';
		qq.pop();
	}
	cout << endl;
	return 0;
}

【输出结果】

【C++初阶】queue的常见操作和模拟实现_第2张图片

三、有关队列的力扣经典题

3.1 二叉树的层序遍历

链接:点击跳转

【题目描述】

【C++初阶】queue的常见操作和模拟实现_第3张图片

【思路】

【C++初阶】queue的常见操作和模拟实现_第4张图片

【代码实现】

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) 
    {
        queue<TreeNode*>q;
        vector<vector<int>> vv;
        int levelSize;

        // 如果根节点不为空,则入队列
        if (root)
        {
            q.push(root);
            // 并且根节点的root一定为1
            levelSize = 1;
        }

        while (!q.empty())
        {
            // 一层一层出
            vector<int> v;
            for (int i = 0;i < levelSize;i++)
            {
                // 记录当前节点
                TreeNode* front = q.front();
                // 删除节点并存入
                q.pop();
                v.push_back(front->val);
                // 并带入它的子节点
                if (front->left) q.push(front->left);
                if (front->right) q.push(front->right);
            }
            vv.push_back(v);
            // 一层出完更新一层的个数
            levelSize = q.size();
        }
        return vv;
    }
};

3.2 用队列实现栈

链接:点击跳转

【题目描述】

【C++初阶】queue的常见操作和模拟实现_第5张图片

【思路】

队列的特点是先进先出,而栈是先进后出,首先定义两个队列

【C++初阶】queue的常见操作和模拟实现_第6张图片

那如何模拟一个栈呢?首先往空的队列入数据

【C++初阶】queue的常见操作和模拟实现_第7张图片

对于栈来说,先出的是4。因此我们可以把1 2 3移到另一个空队列中

【C++初阶】queue的常见操作和模拟实现_第8张图片

【代码实现】

class MyStack {
public:
    MyStack() {}
    
    void push(int x) 
    {
    	// 往不是空的队列插入数据
        if (in.empty())
        {
            out.push(x);
        }
        else
            in.push(x);
    }
    
    int pop() 
    {
    	// 保持一个队列为空
    	// 将一个为空的队列的前n-1个移到空队列
    	// 剩下的那个这是栈顶元素
        if (in.empty())
        {
            while (out.size() > 1)
            {
                int front = out.front();
                out.pop();
                in.push(front);
            }
            int ans = out.front();
            out.pop();
            return ans;
        }
        else // out为空
        {
            while (in.size() > 1)
            {
                int front = in.front();
                in.pop();
                out.push(front);
            }
            int ans = in.front();
            in.pop();
            return ans;
        }
    }
    
    int top() 
    {
        if (in.empty())
        {
           return out.back();
        }
        else 
        {
            return in.back();
        }
    }
    
    bool empty()
    {
        return in.empty() && out.empty();
    }
private:
    queue<int> in;
    queue<int> out;
};

四、模拟实现queue

4.1 简介

【C++初阶】queue的常见操作和模拟实现_第9张图片

queue同样也是一种容器适配器,容器适配器可以被视为一种包装器,它们通过修改底层容器的接口或行为来实现新的功能。通过使用这些容器适配器,开发者可以方便地在不同场景下使用已有容器的功能,并且无需关心底层容器的具体实现。

其实就是STL中封装好的队列,在使用的时候我们不仅可以指定内部的数据类型,还可以指定内部的容器。不指定容器其实也是可以的,模板参数有一个缺省值,默认是deque

4.2 代码实现

#pragma once

namespace wj
{
	template<class T, class Container = deque<T>>
	class queue
	{
	public:
		void push(const T& x)        
		{
			_con.push_back(x);       
		}

		void pop()                   
		{
			_con.pop_front();    
		}

		const T& front()            
		{
			return _con.front();
		}

		const T& back()              
		{
			return _con.back();
		}

		size_t size()                
		{
			return _con.size();      
		}

		bool empty()                 
		{
			return _con.empty();     
		}

	private:
		Container _con;
	};

注意:队列就不能用vector适配了,因为vector没有提供pop_front接口,但是也可以强制适配。只需要改动pop接口

void pop()                   
{
	_con.erase(_con.begin());      
}

但注意,库里是没有强制适配的

【C++初阶】queue的常见操作和模拟实现_第10张图片

为了贴近库,最好不要进行强制适配~

那么为什么库里不支持vector的头删呢?就是因为效率低,头删需要移动数据。

你可能感兴趣的:(C++,c++,开发语言,c语言,visualstudio,list,笔记,学习)