限定只能对线性表一端(表头或表尾)的元素进行插入(入栈)、访问和删除(出栈)等操作的线性表为栈,一端为栈顶,一端为栈底。栈也称后进先出(LIFO)线性表。
1.顺序栈
给予顺序表实现的栈又称为顺序栈。规定顺序表的表尾为站定,对顺序栈的所有操作只能在表尾进行。
#include <iostream>
#include<list>
using namespace std;
typedef int datatype;
constexpr auto N = 100;
//顺序栈的类型定义
typedef struct ssNode {
datatype data[N];
int top; //栈顶下标:top=-1时,表示空栈;top=N-1时,表示栈已满
ssNode():top(-1) {
memset(data, 0, sizeof(data));
}
}seqStack;
//判断栈ss是否为空栈,如果是返回true,否则返回false
bool empty(seqStack ss) {
return ss.top == -1;
}
//向栈ss中压入一个值为x的元素
void push(seqStack& ss, datatype x) {
if (ss.top == N - 1) {
cout << "栈已满,入栈失败!" << endl;
return;
}
ss.data[++ss.top] = x;
}
//创建操作
void create(seqStack &ss) {
int i = -1;
datatype x = 0;
do {
cout << "请输入一个数字" << endl;
cin >> x;
if (x == -1) return;
i++;
ss.top = i;
ss.data[i] = x;
} while (i != N - 1 );
cout << endl;
}
//获取栈顶元素,作为返回值
datatype top(seqStack ss) {
if (empty(ss)) {
cout << "栈空,无栈顶元素可获取!" << endl;
return 0;
}
return ss.data[ss.top];
}
//出栈
void pop(seqStack &ss) {
if (empty(ss)) {
cout << "栈空,出栈失败!" << endl;
return;
}
--ss.top;
}
//遍历栈,不为&ss,即函数里的操作不会影响ss内容
void ss_traverse(seqStack ss) {
while (!empty(ss)) {
cout << top(ss) << endl;
pop(ss);
}
cout << endl;
}
int main()
{
seqStack s1;
create(s1);
ss_traverse(s1);
pop(s1);
ss_traverse(s1);
push(s1, 56);
ss_traverse(s1);
}
2.链栈
基于带头结点的单向链表实现的栈称为链栈。为了提高入栈、出栈的效率,规定链表的第一个结点为栈顶。操作皆针对链表的第一个元素。链栈的操作与单向链表的操作基本类似。(单向链表头结点无数据,双向链表头结点有数据)
#include <iostream>
#include<list>
using namespace std;
typedef int datatype;
constexpr auto N = 100;
//链栈结点的类型定义
typedef struct csNode {
datatype data;
csNode* next;
csNode() :next(NULL) {
data = 0;
}
}*chainStack;
//判断链栈cs是否为空栈,如果是返回true,否则返回false
bool empty(chainStack cs) {
return cs->next == NULL;
}
//向链栈cs中压入一个值为x的元素
void push(chainStack cs, datatype x) {
chainStack q = new csNode;
q->data = x;
q->next = cs->next;
cs->next = q;
}
//获取栈顶元素,作为返回值
datatype top(chainStack cs) {
if (empty(cs)) return 0;
return cs->next->data;
}
//出栈
void pop(chainStack cs) {
if (empty(cs)) return;
chainStack q = cs->next;
cs->next = q->next;
delete q; q = NULL;
}
//遍历链栈
void cs_traverse(chainStack cs) {
if (empty(cs)) {
cout << "栈空" << endl;
}
while (!empty(cs)) {
cout << top(cs) << " ";
cs = cs->next;
}
cout << endl;
}
int main()
{
chainStack c1=new csNode;
push(c1, 2);
push(c1, 5);
push(c1, 6);
push(c1, 7);
cs_traverse(c1);
cs_traverse(c1);
}