栈和队列没有迭代器,他们只是容器适配器,不是容器。容器才有迭代器
文章目录
栈Stack
➡️有关 栈的实现/二叉树的实现 的知识,可以点击这里进行学习⬅️
头文件:stack
本质
cpp
template <class T, class Container = deque<T> > class stack;
- 后进先出
- 栈是一种"容器适配器" ------>栈可能是由list,vector或deque容器(称为底层容器)变化而来
- 底层容器,如果不传,默认是deque
成员函数
-
-
Construct stack (public member function )
-
-
-
Test whether container is empty (public member function )
-
-
-
Return size (public member function )
-
-
-
Access next element (public member function )
-
-
-
Insert element (public member function )
-
-
-
Construct and insert element (public member function )
-
-
-
Remove top element (public member function )
-
-
-
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
成员函数
-
-
Construct queue (public member function )
-
-
-
Test whether container is empty (public member function )
-
-
-
Return size (public member function )
-
-
-
Access next element (public member function )
-
-
-
Access last element (public member function )
-
-
-
Insert element (public member function )
-
-
-
Construct and insert element (public member function )
-
-
-
Remove next element (public member function )
-
-
-
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优先级队列
本质
cpp
template <class T, class Container = vector<T>,
class Compare = less<typename Container::value_type> > class priority_queue;
- 就是个堆 ,默认是大根堆
- 也是容器适配器,默认是vector(因为下标访问用的多)
头文件:queue‼️
不是单独的‼️
成员函数
-
-
Construct priority queue (public member function )
-
-
-
Test whether container is empty (public member function )
-
-
-
Return size (public member function )
-
-
-
Access top element (public member function )
-
-
-
Insert element (public member function )
-
-
-
Construct and insert element (public member function )
-
-
-
Remove top element (public member function )
-
-
-
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>即可
- 入栈序列,每次入栈一个值
- 如果入后的栈顶数据跟出栈序列匹配,------>出栈------>不断匹配,不断出栈
- 入栈序列入完了,就结束了
二叉树的层序遍历
原题链接: 二叉树的层序遍历

这个题目给的是二叉树,要求是输出一个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.进一步实现题目要求
在上面的条件下,我们一层一层输入数据
- levelsize作为内部的循环条件
- 在"插入树根"的时候,levelsize置为1------因为第一层只有一个节点
- 然后的循环中,只将levelsize个节点的子节点插入队列中
- 插入结束之后的队列的size,就是下一层的节点个数
- 在"插入树根"的时候,levelsize置为1------因为第一层只有一个节点
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;
}
};