队列/栈基本原理
计算机本质上有两种存储数据的方式,一种是顺序结构也就是我们之前说的数组,另外一种是链式结构也就是我们之前聊的链表,之后我们聊的所有的数据结构都是基于这两种存储方式来实现的,也就是说后面我们学习的数据结构都是通过逻辑上的构建,用这两种存储方式模拟而成的。
本文我们会详细的介绍两种基本的数据结构队列和栈,在后续的文章中我们会详细的讲解如何用代码具体的实现。
本质上来说,栈和队列是【受限制】的数据结构,我们之前说对于所有的数据结构来说,基本的操作就是“增删改查创”,也就是他受限制的操作也就是这5个中的某些操作,因此他提供的API就是不完整的。
在我们之前学习的过程中我们知道,只要内存够的情况下,并且你的操作或者说索引不越界的情况,那你可以随便的进行“增删改查”,但是对于栈和队列,他们的操作就是受限制的,他们的限制是:**队列只能在一端进行插入操作,而另一端只能进行删除操作;而栈只能在一端进行插入和删除操作。**有同学会说这不就是阉割版本的数组或者链表吗,有什么用处,没原来的方便。但是你换一个思路想,在某些场景下,例如排队、发书收书等场景下,不需要中间过多的操作,并且在这样的逻辑下,你根本不需要考虑中间元素是否会发生改变,较少和优化了API的设计不也是一种优化吗!
因此栈和队列会在某些场景下有其独特的使用方式,在这些场景下我们如果有相对应的API会方便很多。
回过头来我们再说队列和栈,形象地理解,队列只允许在队尾插入元素,在队头删除元素,栈只允许在栈顶插入元素,从栈顶删除元素。这个图中把栈竖着画,队列横着画,只是为了更形象,但实际上它们底层都是数组和链表实现的,如图所示:

队列就想排队买票,栈就像垒盘子,因此我们常说队列是一种「先进先出」的数据结构,栈是一种「先进后出」的数据结构,就是这个道理。
// 队列的基本 API
template <typename E>
class MyQueue {
public:
// 向队尾插入元素,时间复杂度 O(1)
void push(const E& e);
// 从队头删除元素,时间复杂度 O(1)
E pop();
// 查看队头元素,时间复杂度 O(1)
E peek() const;
// 返回队列中的元素个数,时间复杂度 O(1)
int size() const;
};
// 栈的基本 API
template <typename E>
class MyStack {
public:
// 向栈顶插入元素,时间复杂度 O(1)
void push(const E& e);
// 从栈顶删除元素,时间复杂度 O(1)
E pop();
// 查看栈顶元素,时间复杂度 O(1)
E peek() const;
// 返回栈中的元素个数,时间复杂度 O(1)
int size() const;
};
不同语言下的API提供方式可能不同,这里提供的是C++语言的名称,我们可以尝试着用数组和链表来模拟出栈和队列,这是我们学习栈和队列的必经之路!!!
314

被折叠的 条评论
为什么被折叠?



