栈
栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
顺序栈
顺序栈是用数组实现的栈,
结构体定义
提示:
- 应有栈顶和栈底指针
typedef struct {
int *top;//栈顶指针
int *base;//栈底指针
}SqStack;
初始化
提示:
- 动态内存分配是否成功?
#define MAXSIZE 25
bool initStack(SqStack &s) {
s.base = new int[MAXSIZE];//使用栈底指针动态内存分配
if (!s.base) {//动态内存分配是否成功?
return false;
}
s.top = s.base;
return true;
}
插入元素
提示:
- 栈是否已满?
- 栈顶指针是否移动?
void push(SqStack &s, int data) {
if (MAXSIZE == s.top - s.base) {//栈是否已满?
cout << "栈已满!" << endl;
return;
}
*(s.top) = data;
s.top++;//栈顶指针是否移动?
}
删除元素
提示:
- 栈是否为空?
- 栈顶指针是否移动?
int pop(SqStack &s) {
if (s.top == s.base) {//栈是否为空?
cout << "栈为空!" << endl;
return 0;
}
int data = *(s.top - 1);
s.top--;//栈顶指针是否移动?
return data;
}
销毁顺序栈
无提示
void destoryStack(SqStack &s) {
delete[] s.base;
s.base = s.top = NULL;
}
全部代码及测试代码
#include <iostream>
#define MAXSIZE 25
using namespace std;
typedef struct {
int *top;
int *base;
}SqStack;
bool initStack(SqStack &s) {
s.base = new int[MAXSIZE];
if (!s.base) {
return false;
}
s.top = s.base;
return true;
}
void push(SqStack &s, int data) {
if (MAXSIZE == s.top - s.base) {
cout << "栈已满!" << endl;
return;
}
*(s.top) = data;
s.top++;
}
int pop(SqStack &s) {
if (s.top == s.base) {
cout << "栈为空!" << endl;
return 0;
}
int data = *(s.top - 1);
s.top--;
return data;
}
void destoryStack(SqStack &s) {
delete[] s.base;
s.base = s.top = NULL;
}
int main(void) {
SqStack s;
initStack(s);
int n, data;
cout << "请输入入栈元素的个数:";
cin >> n;
while (n--) {
cout << "请输入元素值:";
cin >> data;
push(s, data);
}
cout << "出栈元素为:" << pop(s) << endl;
cout << "出栈元素为:" << pop(s) << endl;
destoryStack(s);
system("pause");
return 0;
}
链栈
结构体定义
提示:
- 对于每个结点,需要有数据域和指针域
- 要有栈顶指针
typedef struct LinkNode {
int data;//数据域
LinkNode *next;//指针域
}LinkNode;
typedef struct {
LinkNode *top;//要有栈顶指针
}LinkStack;
初始化
提示:
- 栈顶指针是否初始化?
bool initStack(LinkStack &L) {
L.top = NULL;//栈顶指针是否初始化?
return true;
}
插入元素
这里和大家的理解可能有出入,如果按栈的结构来组织元素的话栈顶指针指向的是单链表中的最后一个元素,而单链表只能从前向后访问,如果每次栈顶指针指向新的元素那么就会失去前面元素的"控制权",意味着由栈顶指针只能查找到一个元素(即最新的元素).所以这里我们使用类似于头插法的方法插入元素,具体见下图:
void push(LinkStack &L, int data) {
LinkNode *e = new LinkNode;
e->data = data;
e->next = L.top;
L.top = e;
}
删除元素
提示:
- 栈可能为空
- 记得回收内存
int pop(LinkStack &L) {
if (!L.top) {//栈可能为空
cout << "栈为空!" << endl;
return 0;
}
LinkNode *e = L.top;
int data = e->data;
L.top = e->next;
delete e;//记得回收内存
return data;
}
全部代码及测试代码
#include <iostream>
using namespace std;
typedef struct LinkNode {
int data;
LinkNode *next;
}LinkNode;
typedef struct {
LinkNode *top;
}LinkStack;
bool initStack(LinkStack &L) {
L.top = NULL;
return true;
}
void push(LinkStack &L, int data) {
LinkNode *e = new LinkNode;
e->data = data;
e->next = L.top;
L.top = e;
}
int pop(LinkStack &L) {
if (!L.top) {
cout << "栈为空!" << endl;
return 0;
}
LinkNode *e = L.top;
int data = e->data;
L.top = e->next;
delete e;
return data;
}
int main(void) {
LinkStack L;
initStack(L);
int n,data;
cout << "请输入入栈的个数:";
cin >> n;
while (n--) {
cout << "请输入入栈的元素:";
cin >> data;
push(L, data);
}
cout << "出栈元素为:" << pop(L) << endl;
cout << "出栈元素为:" << pop(L) << endl;
system("pause");
return 0;
}