持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情
1、写在前面
大家好,我是翼同学。今天文章的内容是:
- 栈的介绍以及C++实现
2、内容
2.1、什么是栈?
(1) 栈的概念
栈属于线性结构,其逻辑结构和线性表相同,具有线性结构的共同特征。
栈的定义如下:
栈(stack)是只允许在表的一端,进行插入或删除操作的线性表
(2) 栈的特点
栈的基本特点就是先进后出(First In Last Out),也称为后进先出(Last In First Out)。也就是说,最先入栈的数据元素会最后一个出栈,最晚入栈的元素会最先出栈。
比如我们将书籍放在大小合适的纸箱子里,一本一本地进去叠好后,一开始放进去的书在纸箱子的最底下,此时该书只能是最后一个拿出纸箱子,因为我们只能把叠在上面的书拿出来后才能拿到最底下的书(先进后出),这是因为规定了纸箱子的另一端无法拿到书。栈就是这样的例子。在程序设计中,有时需要按与保存数据时相反的顺序来使用数据,这就需要用栈来实现。
(3) 术语说明
有关栈的一些术语如下:
- 栈顶(
Top):允许进行插入或删除操作的一端,称为栈顶; - 栈底(
Bottom): 与栈顶相对的另一端称为栈底; - 入栈(
Push):在栈顶位置插入数据元素的操作称为入栈(有时也称为进栈、压栈) - 出栈(
Pop):删除栈顶元素的操作称为出栈。(也叫弹栈、退栈) - 空栈:不含数据元素的栈称为空栈
备注:
当栈已满并且又有元素进栈时,则发生上溢、当栈空时,若再出栈,则发生下溢。
(4) 栈的抽象数据类型定义
#include <iostream>
using namespace std;
template <class T>
class ADTStack {
public:
virtual bool empty() const = 0; // 判断是否为空栈
virtual int size() const = 0; // 返回栈中的元素个数
virtual void push(const T& x) =0; // 入栈,x成为新的栈顶元素
virtual T pop() = 0; // 出栈,若栈非空,则删除栈顶元素
virtual const T& getTop() const=0; // 返回栈顶元素(但不弹出)
virtual void clear() = 0; // 清空栈
virtual ~ADTStack() {} //虚析构函数
};
2.2、顺序栈的C++实现
顺序栈:利用顺序存储结构实现的栈称为顺序栈
和顺序表一样,栈中的元素利用一个一维数组来存储,将数组小下标端设为栈底,而栈顶元素是随着插入和删除操作而时刻动态变化的。为了方便操作,我们会使用一个变量top来存放栈顶元素的索引值,因此top也称为栈顶指针。我们将top赋值为-1表示空栈。当有一个元素压入栈时,top会自增加1,此时就可以将数据写入top所指向的单元中。同样的,出栈时,top会减1.
(1) 类定义
顺序栈的类定义如下:
template <class T>
class seqStack : public ADTStack<T> {
private:
T *array; // 存放栈中元素的数组
int top; // 栈顶指针,指向栈顶元素
int size; // 栈的大小
void doubleSize(); // 容量扩大一倍,扩大栈的空间
public:
// 构造函数
SeqStack(int initSize = 16 );
// 析构函数
~SeqStack() {
delete [] array;
}
// 请空栈
void clear() {
top = -1;
}
// 判断是否为空栈
bool empty() const {
return top == -1;
}
// 求长度
int size() const {
return top + 1;
}
// 压栈
void push(const T& val);
// 出栈
T pop();
// 取栈顶元素
const T& getTop() const;
};
下面的具体的函数定义。
(2) 构造函数
(3) 压栈
(4) 出栈
(5) 取栈顶元素
(6) 扩容
2.3、链栈的C++实现
链栈:利用链式存储结构实现的栈称为链栈
链栈中的结点结构和单链表中的一样,并且链栈由栈顶指针top唯一确定。也就是说,top指针直接指向栈顶元素,当top==NULL时为空栈。
(1) 类定义
template <class T>
class LinkStack: public ADTStack<T> {
private:
struct Node{
T data;
Node* next;
Node() {
next = NULL;
}
Node(const T& val, Node* p = NULL) {
data = val;
next = p;
}
};
Node *top;
public:
// 构造函数
LinkStack(): head(0) {
top = new Node();
}
// 析构函数
~LinkStack() {
clear();
}
// 请空
void clear();
// 判断是否为空栈
bool empty() const {
return top == NULL;
}
// 求栈的长度
int size()const;
// 进栈
void push(const T &val);
// 出栈
T pop();
// 返回栈顶元素
const T& getTop() const;
};
(2) 清空
(3) 求栈中的元素个数
(4) 进栈
(5) 出栈
(6) 判空
3、写在最后
好了,文章的内容就到这里,感谢观看。