一. 栈的基本介绍
1. 基本概念
栈是一种线性表 是一种特殊的数据结构
栈顶:进行数据插入和删除操作的一端
另一端叫做栈底
压栈:插入数据叫做压栈 压栈的数据在栈顶
出栈: 栈的删除操作叫做出栈 出栈操作也是在栈顶
栈遵循一个原则 叫做后进先出
(比如说子弹的弹夹 其实就是一种设计好的栈结构)
画图表示如下
2. 代码结构 (动态数组实现)
因为数组模式相对于链表模式来说 尾插的操作消耗更好些
此外因为静态的数组不能变更空间大小 所以说我们这里用动态数组的代码来实现一下
typedef int STDateType;typedef struct Stack
{int* a;//存储数据的大小int Top;//栈顶int capacity;//容量大小
}ST;
二. 接口函数实现
1. 初始化栈
这个很简单 初始化栈里面的三个值就好
代码表示如下
//初始化
void STInit(ST* ps)
{assert(ps);ps->a = (STDateType*)malloc(sizeof(STDateType)*4);if (ps->a == NULL){perror("malloc fail");return;}ps->Top = 0;//top是栈顶元素的下一个位置ps->capacity = 4;
}
我们这里要注意Top初始化值的不同后面几个操作Top也不同
初始化为0表示栈顶元素的下一个位置,初始化为1表示栈顶的位置
2. 压栈
这里我们需要考虑一个问题
我们压栈的时候是否空间满了呢?
所以在压栈之前我们先判断一下Top和capacity来看看栈空间是否满了
整体代码表示如下
void STPush(ST* ps, STDateType x)
{assert(ps);if (ps->Top == ps->capacity){STDateType* tmp = (STDateType*)realloc(ps->a, sizeof(STDateType) * ps->capacity * 2);if (tmp == NULL){perror("realloc fail");return;}ps->a = tmp;ps->capacity *= 2;}ps->a[ps->Top] = x;ps->Top++;
}
来看看效果:
可以运行
3. 出栈
这个很简单 只需要考虑一个问题
是否删除了过多的数据导致错误
代码表示如下
//出栈
void STPop(ST* ps)
{assert(ps);assert(!STEmpty(ps));ps->Top--;
}
我们在打印压栈操作的时候已经用过我们的出栈操作,否则无法打印
效果如下:
4. 找到个数
这个很简单 返回Top的值就可以
//个数
int STSize(ST* ps)
{assert(ps);return ps->Top;
}
5. 判断是否为空
这个也很简单 两行代码搞定
//判断空
bool STEmpty(ST* ps)
{assert(ps);return ps->Top==0;
}
6. 摧毁栈
释放开辟出的内存空间 之后再指针置空就可以
这个也很简单 这里就不过多介绍了
//销毁
void STDestroy(ST* ps)
{assert(ps);free(ps->a);ps->capacity = 0;ps->Top = 0;ps->a = NULL;
}
7.top的位置
//top的位置
STDateType STTop(ST* ps)
{assert(ps);assert(!STEmpty(ps));return ps->a[ps->Top - 1];
}
也很简单,根据前面我们top初始化的值,这里需要top-1
三. 两道简单的题目
题目一
一个栈的初始状态为空。现将元素1、2、3、4、5、A、B、C、D、E依次入栈,然后再依次出栈,则元素出栈的
顺序是( )。
A 12345ABCDE
B EDCBA54321
C ABCDE12345
D 54321EDCBA
答案是B 遵循后进先出的原则
题目二
若进栈序列为 1,2,3,4 ,进栈过程中可以出栈,则下列不可能的一个出栈序列是()
A 1,4,3,2 B 2,3,4,1
C 3,1,4,2 D 3,4,2,1
首先来看A选项
我们先压栈1 再出栈1 压栈 2 3 4 再依次出栈就可以 没问题
B选项
我们先压栈 1 2 出栈2 再压栈3 4 再依次出栈就可以 没有问题
C选项
我们先压栈123 出栈3 之后再出栈1 这个就不对了 要想出栈1 必须先出栈2
所以答案是C
D选项
我们先压栈 1 2 3 再出栈3 然后压栈4 再依次出栈就可以 没有问题
以上便是本文所以内容了,如有错误请各位大佬不吝赐祭,感谢留言