一、基础知识
1.1 四个问题
1. C++中stack,queue 是容器么?
2. 我们使用的stack,queue是属于那个版本的STL?
3. 我们使用的STL中stack,queue是如何实现的?
4. stack,queue 提供迭代器来遍历空间么?
首先,stack、queue是STL里边的两个标准库,栈后进先出,队列先进先出。
STL有多个版本,要知道我们使用的STL是哪个版本,才能知道对应的栈和队列的实现原理。三个最为普遍的STL版本:
HP STL 其他版本的C++ STL,一般是以HP STL为蓝本实现出来的,HP STL是C++ STL的第一个实现版本,而且开放源代码。
P.J.Plauger STL 由P.J.Plauger参照HP STL实现出来的,被Visual C++编译器所采用,不是开源的。
SGI STL 由Silicon Graphics Computer Systems公司参照HP STL实现,被Linux的C++编译器GCC所采用,SGI STL是开源软件,源码可读性甚高。
接下来介绍的栈和队列也是SGI STL里面的数据结构, 知道了使用版本,才知道对应的底层实现。
栈提供了以下常用接口:
stack<int>s;
s.empty(); //如果栈为空则返回true, 否则返回false;
s.size(); //返回栈中元素的个数
s.top(); //返回栈顶元素, 但不删除该元素
s.pop(); //弹出栈顶元素, 但不返回其值
s.push(); //将元素压入栈顶
栈中所有元素必须符合先进后出规则,所以栈不提供走访功能,也不提供迭代器(iterator)。 不像是set 或者map 提供迭代器iterator来遍历所有元素。
关于迭代器的相关知识见:C++迭代器(STL迭代器)iterator详解
栈是以底层容器完成其所有的工作,对外提供统一的接口,底层容器是可选的(可以控制使用哪种容器来实现栈的功能)。所以STL中栈往往不被归类为容器,而被归类为container adapter(容器适配器)。
栈的内部结构如下图所示(图来自于carl),可见栈的底层实现可以是vector,deque,list , 主要就是数组和链表的底层实现。
SGI STL中,如果没有指定底层实现的话,默认是以deque为缺省情况下栈的低层结构。deque是一个双向队列,只要封住一段,只开通另一端就可以实现栈的逻辑了。
也可以定义vector方式实现栈:
std::stack<int, std::vector<int> > third; // 使用vector为底层容器的栈
队列中的元素必须符合先进先出的要求,同样不允许有遍历行为,不提供迭代器, SGI STL中队列一样是以deque为缺省情况下的底部结构。 STL 队列也不被归类为容器,而被归类为container adapter( 容器适配器)。
1.2 栈和队列的相互模拟
232.用栈实现队列、225.用队列实现栈_清榎的博客-CSDN博客
题目很简单,主要可以熟悉栈和队列的操作。栈实现队列时使用两个栈,每次出队时从一个栈挪至另一个在栈顶出栈即可。队列实现栈时类似操作,两个队列,出栈时全部出队至另一个(最后一个元素无需入队,直接出队即可)。
二、经典题目
2.1 栈的经典题目
20. 有效的括号、1047. 删除字符串中的所有相邻重复项、150. 逆波兰表达式求值_清榎的博客-CSDN博客
2.1.1有效的括号
此题思路十分简单,遍历整个字符串,遇到左括号就入栈,遇到右括号就出栈进行比对查看是否匹配,若出栈时栈空表示不匹配返回false。全部遍历结束且栈空时表示括号匹配完成,返回true。
2.1.2 字符串去重问题
使用栈比对,相同就出栈,最后栈中剩余元素即为结果。
2.1.3 逆波兰表达式
经典栈的问题,数字入栈,符号连续出栈两个数字进行计算。
2.2 队列经典题目
239. 滑动窗口最大值(单调队列)、347. 前k个高频元素_清榎的博客-CSDN博客
2.2.1 滑动窗口最大值
使用了单调队列进行解决。本题主要是想清楚队列中无需存储所有窗口内元素,只存储可能成为最大值的元素即可,同时也要保证队列中的元素由大到小。
这个维护元素单调递减的队列就叫做单调队列,即单调递减或单调递增的队列。C++中没有直接支持单调队列,需要我们自己来一个单调队列 。
2.2.2 前k个高频元素
这道题引出另一种队列就是优先级队列。优先级队列其实就是一个披着队列外衣的堆,因为优先级队列对外接口只是从队头取元素,从队尾添加元素,再无其他取元素的方式,看起来就是一个队列。
而且优先级队列内部元素是自动依照元素的权值排列。缺省情况下priority_queue利用max-heap(大顶堆)完成对元素的排序,这个大顶堆是以vector为表现形式的complete binary tree(完全二叉树)。