栈(stack)又名堆栈,它是一种仅在表尾进行插入和删除操作的线性表。运行插入和删除元素的一端称为栈顶,另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
顺序栈
顺序栈是指采用顺序存储的栈。它是利用一组地址连续的存储单元存放自栈底到栈顶的数据元素,同时附设一个指针(top)指示当前栈顶的位置。
栈的顺序存储类型可用一个结构体表示:
#define MAXSIZE 10
typedef struct {
int data[MAXSIZE]; // 静态数组存放栈中元素
int top; // 栈顶指针
}SqStack;
顺序栈的基本运算:初始化、进栈、出栈、取栈顶元素、判断栈空
#include <iostream>
#define MAXSIZE 10
typedef struct {
int data[MAXSIZE]; // 静态数组存放栈中元素
int top; // 栈顶指针
}SqStack;
// 初始化栈
void InitStack(SqStack& S)
{
S.top = -1;
}
// 判断栈空
bool Empty(SqStack& S)
{
if (S.top == -1) {
return true;
}
else {
return false;
}
}
// 新元素入栈
bool push(SqStack& S, int x)
{
if (S.top == MAXSIZE) { // 栈满报错
return false;
}
S.top += 1; // 栈顶指针先加1
S.data[S.top] = x; // 新元素入栈
return true;
}
// 新元素出栈
bool pop(SqStack& S, int& x)
{
if (S.top == -1) { // 栈空报错
return false;
}
x = S.data[S.top]; // 取出栈顶元素
S.top -= 1; // 栈顶指针减1
return true;
}
// 取栈顶元素
int peek(SqStack& S)
{
return S.data[S.top];
}
int main()
{
SqStack S;
InitStack(S);
push(S, 1);
push(S, 2);
push(S, 3);
int a = peek(S);
std::cout << a << std::endl;
for (int i = 0; i <= S.top; i++) {
std::cout << S.data[i] << std::endl;
}
return 0;
}
链栈
链栈是指采用链式存储的栈。链栈通常采用单链表来实现,因此其结构与单链表的结构相同。由于栈的插入和删除操作仅限制在栈顶位置进行,所以采用单链表的表头指针作为栈顶指针。
为了操作方便,使用带头节点的单链表来实现链表。数据入栈或出栈时,使表头节点的指针指向新的表首节点即可,再入栈时,需要为新的数据元素动态的开辟存储单元,并修改头结点的指针域;而在出栈时,除了改变头结点的指针域,还要释放原栈顶元素所占用的空间。
#include <iostream>
typedef struct LNode {
int data; // 数据域
struct LNode* next; // next指针
}LNode;
// 新元素入链栈
bool push(LNode* p, int e)
{
if (p == nullptr) {
return false;
}
LNode* s = new LNode;
if (s == nullptr) {
return false;
}
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
// 从链栈栈顶弹出元素
bool pop(LNode* p, int& e)
{
if (p == nullptr || p->next == nullptr) { // 栈空则报错
return false;
}
LNode* s = p->next;
e = s->data;
// 元素取出后,销毁节点
p->next = s->next;
delete s;
return true;
}
// 链栈判断空
bool Empty(LNode* p)
{
if (p->next == nullptr) {
return true;
}
return false;
}
// 取栈顶元素
bool peek(LNode* p, int& e)
{
if (p == nullptr || p->next == nullptr) { // 栈空则报错
return false;
}
LNode* s = p->next;
e = s->data;
return true;
}
int main()
{
LNode* dummyHead = new LNode;
dummyHead->next = nullptr;
bool judge1 = Empty(dummyHead);
std::cout << "是否为空:" << judge1 << std::endl;
int x = 0;
push(dummyHead, 1);
push(dummyHead, 2);
push(dummyHead, 3);
pop(dummyHead, x);
std::cout << x << std::endl;
bool judge2 = Empty(dummyHead);
std::cout << "是否为空:" << judge2 << std::endl;
LNode* p = dummyHead->next; // 遍历指针
while (p != nullptr) {
std::cout << p->data << std::endl;
p = p->next;
}
int y = 0;
peek(dummyHead, y);
std::cout << "栈顶元素:" << y << std::endl;
return 0;
}
参考: