【stack、queue、deque、priority_queue】C++ 栈 / 队列 / 优先级队列全解析!手撕实现 + 二叉树层序遍历(附源码)

栈和队列没有迭代器,他们只是容器适配器,不是容器。容器才有迭代器

文章目录

栈Stack

➡️有关 栈的实现/二叉树的实现 的知识,可以点击这里进行学习⬅️






头文件:stack






本质

cpp 复制代码
template <class T, class Container = deque<T> > class stack;
  • 后进先出
  • 栈是一种"容器适配器" ------>栈可能是由list,vector或deque容器(称为底层容器)变化而来
  • 底层容器,如果不传,默认是deque





成员函数

    • empty

      Test whether container is empty (public member function )

    • size

      Return size (public member function )

    • top

      Access next element (public member function )

    • push

      Insert element (public member function )

    • emplace

      Construct and insert element (public member function )

    • pop

      Remove top element (public member function )

    • swap

      Swap contents (public member function )






实现

stack.h

cpp 复制代码
#pragma once

namespace lcj
{
	template<class T, class Container = vector<T>>
	class stack
	{
	public:
	/// <summary>
	/// 不用写构造函数,因为container是自定义类型,会调用对应的构造函数
	/// </summary>
	/// 
		void push(const T& x)
		{
			_con.push_back(x);
		}

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

		const T& top() const
		{
			return _con.back();///不能通过'[ ]'访问,当container是list时,没有这个功能
		}

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

		bool empty()const
		{
			return _con.size() == 0;
		}



	private:
		Container _con;
	};
}





按需实例化:

在.h中写的类中的成员函数,并不会全都被实例化,编译器只实例化使用的接口------>编译器不检查细节语法,有时候不会报错,但是使用的时候还是会发生错误------>写函数的时候还是要写一个检查一个











队列queue

本质

cpp 复制代码
template <class T, class Container = deque<T> > class queue;
  • 先进先出
  • 也是一种"容器适配器" ------>栈可能是由list或deque容器(称为底层容器)变化而来
  • 底层容器,如果不传,默认是deque





成员函数

    • empty

      Test whether container is empty (public member function )

    • size

      Return size (public member function )

    • front

      Access next element (public member function )

    • back

      Access last element (public member function )

    • push

      Insert element (public member function )

    • emplace

      Construct and insert element (public member function )

    • pop

      Remove next element (public member function )

    • swap

      Swap contents (public member function )






实现

queue.h

cpp 复制代码
#pragma once 

namespace lcj
{
	template<class T, class Container = list<T>>
	class queue
	{
	public:
		/// <summary>
		/// 不用写构造函数,因为container是自定义类型,会调用对应的构造函数
		/// </summary>
		/// 
		void push(const T& x)
		{
			_con.push_back(x);
		}

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

		const T& back() const
		{
			return _con.back();///不能通过'[ ]'访问,当container是list时,没有这个功能
		}

		const T& front() const
		{
			return _con.front();///不能通过'[ ]'访问,当container是list时,没有这个功能
		}

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

		bool empty()const
		{
			return _con.size() == 0;
		}



	private:
		Container _con;
	};
}










deque双端队列

stack和queue的缝合

成员函数

函数分类 函数名 功能说明
构造 / 析构 / 赋值 (constructor) 构造 deque 容器(公有成员函数)
(destructor) 销毁 deque 容器(公有成员函数)
operator= 给 deque 容器赋值(公有成员函数)
迭代器(Iterators) begin 返回指向容器起始位置的迭代器(公有成员函数)
end 返回指向容器末尾位置的迭代器(公有成员函数)
rbegin 返回指向容器反向起始位置的反向迭代器(公有成员函数)
rend 返回指向容器反向末尾位置的反向迭代器(公有成员函数)
cbegin 返回指向容器起始位置的 const 迭代器(公有成员函数)
cend 返回指向容器末尾位置的 const 迭代器(公有成员函数)
crbegin 返回指向容器反向起始位置的 const 反向迭代器(公有成员函数)
crend 返回指向容器反向末尾位置的 const 反向迭代器(公有成员函数)
容量管理(Capacity) size 返回容器当前存储的元素数量(公有成员函数)
max_size 返回容器可容纳的最大元素数量(公有成员函数)
resize 改变容器的大小(公有成员函数)
empty 检测容器是否为空(公有成员函数)
shrink_to_fit 释放容器未使用的内存,收缩到适配当前元素大小(公有成员函数)
元素访问(Element access) operator\[\] 访问容器中指定下标位置的元素(公有成员函数)
at 访问容器中指定下标位置的元素,带越界检查(公有成员函数)
front 访问容器的第一个元素(公有成员函数)
back 访问容器的最后一个元素(公有成员函数)
内容修改(Modifiers) assign 给容器重新赋值,覆盖原有内容(公有成员函数)
push_back 在容器末尾添加一个元素(公有成员函数)
push_front 在容器开头插入一个元素(公有成员函数)
pop_back 删除容器末尾的最后一个元素(公有成员函数)
pop_front 删除容器开头的第一个元素(公有成员函数)
insert 在容器指定位置插入元素(公有成员函数)
erase 删除容器指定位置的元素(公有成员函数)
swap 交换两个 deque 容器的内容(公有成员函数)
clear 清空容器内的所有元素(公有成员函数)
emplace_front 在容器开头直接构造并插入一个元素(公有成员函数)
emplace_back 在容器末尾直接构造并插入一个元素(公有成员函数)
分配器(Allocator) get_allocator 获取容器使用的内存分配器(公有成员函数)
非成员函数重载 relational operators deque 容器的关系比较运算符(函数模板)
swap 交换两个 deque 容器的内容(函数模板)










priority_queue优先级队列

➡️有关 堆和二叉树 的知识,可以点击这里进行学习【数据结构精讲】堆与二叉树从底层原理到代码落地:堆的构建 / 调整 / 排序 + 二叉树遍历 / 操作(附完整 C++ 源码 + LeetCode 题解)⬅️

本质

cpp 复制代码
template <class T, class Container = vector<T>,
  class Compare = less<typename Container::value_type> > class priority_queue;
  • 就是个默认是大根堆
  • 也是容器适配器,默认是vector(因为下标访问用的多)





头文件:queue‼️

不是单独的‼️






成员函数

    • (constructor)

      Construct priority queue (public member function )

    • empty

      Test whether container is empty (public member function )

    • size

      Return size (public member function )

    • top

      Access top element (public member function )

    • push

      Insert element (public member function )

    • emplace

      Construct and insert element (public member function )

    • pop

      Remove top element (public member function )

    • swap

      Swap contents (public member function )






应用

大根堆

  • priority_queue<int, vector<int>, less<int>> pq;中的: less<int>也可以不写,是默认的,这时候是大根堆------>打印出来是从大到小的
cpp 复制代码
#include<queue>

using namespace std;///必须在#include"stack.h"的前面,这样,如果stack.h里面有std::cout这种函数也没问题
 

int main()
{
	priority_queue<int, vector<int>, less<int>> pq;
	pq.push(3);
	pq.push(777);
	pq.push(66);
	pq.push(88);
	pq.push(22);
	pq.push(9);

	while (!pq.empty())
	{
		cout << pq.top() << endl;
		pq.pop();
	} 
	return 0;
}



小根堆

------>从小到大打印

只需要改 less<int>greater<int>即可











栈的压入、弹出序列

  1. 入栈序列,每次入栈一个值
  2. 如果入后的栈顶数据跟出栈序列匹配,------>出栈------>不断匹配,不断出栈
  3. 入栈序列入完了,就结束了





二叉树的层序遍历

原题链接: 二叉树的层序遍历

这个题目给的是二叉树,要求是输出一个vector<vector<int>>类型的数组

1.实现层序遍历:

队列存节点指针,下来一个节点,放一个节点的子节点

  • 创造一个队列,存的是TreeNode*类型的指针: queue<TreeNode*> q;

  • 插入树根:q.push(root);

  • while循环遍历:

    • 条件 : 队列中还有元素: while(!q.empty())

    • 循环体:

      • 得到队列头节点:TreeNode* thisnode=q.front();

      • 头删:q.pop();

      • 操作:......

      • 将这个节点的孩子放进队列:

        if(thisnode->left)

        q.push(thisnode->left);

        if(thisnode->right)

        q.push(thisnode->right);

cpp 复制代码
        queue<TreeNode*> q;
        int levelsize=0;

        if(root)
        {
            q.push(root); 
        }

        while(!q.empty())
        {   
                TreeNode* thisnode=q.front(); 
                q.pop();
            
            //对thisnode的操作

                if(thisnode->left)
                    q.push(thisnode->left);

                if(thisnode->right)
                    q.push(thisnode->right); 
        }  



2.进一步实现题目要求

在上面的条件下,我们一层一层输入数据

  1. levelsize作为内部的循环条件
    1. 在"插入树根"的时候,levelsize置为1------因为第一层只有一个节点
      1. 然后的循环中,只将levelsize个节点的子节点插入队列中
    2. 插入结束之后的队列的size,就是下一层的节点个数
cpp 复制代码
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) 
    {
        vector<vector<int>> vv;
        queue<TreeNode*> q;
        int levelsize=0;

        if(root)
        {
            q.push(root);
            levelsize=1; 
        }

        while(!q.empty())
        {
            vector<int> v;

            while(levelsize--)////////////////////////////////levelsize作为内部的循环条件
            {
                TreeNode* thisnode=q.front();
                q.pop();
                
                
                v.push_back(thisnode->val);//操作

                if(thisnode->left)
                    q.push(thisnode->left);

                if(thisnode->right)
                    q.push(thisnode->right);

            }
            
            
            vv.push_back(v);  //////////////////////////////////////////操作
            levelsize=q.size();/////////////////////////////插入结束之后的队列的size,就是下一层的节点个数
        }

        return vv;
        
    }
};









155. 最小栈

相关推荐
兵哥工控1 小时前
高精度微秒延时函数实现顺控工控项目实例
c++·mfc·硬件高精度计时器
j_xxx404_1 小时前
Linux线程池硬核解析:从固定线程池、单例线程池到线程安全、死锁与锁模型|附源码
linux·运维·服务器·c++·安全·ai
zhangakirn1 小时前
Systems Biology Part 1学习笔记
笔记·学习
牛油果子哥q1 小时前
【C++静态成员】C++静态成员终极精讲:静态成员变量、静态成员函数、内存布局、对象共享机制、工程实战、深浅坑点与面试满分总结
c++·面试
奋斗的小方1 小时前
Java进阶篇1-2:泛型
java·开发语言·windows
晚风吹红霞1 小时前
深入剖析二叉搜索树:从原理到实现,从单key到key/value模型
c++
say_fall1 小时前
模拟量输入输出技术超详细知识点总结
linux·开发语言·嵌入式硬件·学习·php
我是一颗柠檬1 小时前
C++最全面复习:从入门到精通(2026年)
开发语言·c++·visualstudio
lilili也1 小时前
C++:lamda表达式
c++