一、基础知识
- 栈的定义:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。
- 原则:后进先出 或 先进后出
- 实现:数组栈 和 链栈
数组栈:实现极其简单,但是浪费空间
链栈:① 栈底在链头,栈顶在链尾 :尾插尾删,最好用双向链栈(此结构操作需要知道前一个结点)② 栈底在链尾,栈顶在链头:头插头删
总结:
结合数组栈和链栈的优缺点,最好采用数组栈
二、接口
结构体:
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
2.1 初始化
//初始化
void StackInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->top = 0;
ps->capacity = 0;
}
TIP:
top
可以为0也可以是-1,
当top
为0,top指向栈顶下一个元素,在入栈时候需要注意先放后++;
当top
为-1,top指向栈顶元素,在入栈时候需要注意先++后放;
2.2 入栈
//入栈
void StackPush(ST* ps, STDataType x)
{
assert(ps);
//判断空间是否足够
//空间不足
if (ps->top == ps->capacity)
{
int newCapacity = (ps->capacity == 0) ? 4 : ps->capacity * 2;
STDataType* tmp = realloc(ps->a, sizeof(STDataType) * newCapacity);
//开辟失败
if (tmp == NULL)
{
printf("realloc fail!");
exit(0);
}
//开辟成功
ps->a = tmp;
ps->capacity = newCapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
2.3 出栈
//出栈
void StackPop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
ps->top--;
}
2.4 取栈顶元素
//取栈顶元素
STDataType StackTop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
return ps->a[ps->top - 1];
}
出栈和取栈顶元素的代码虽然简单,但也要注意判断栈为空的情况,即
assert(ps->top>0)
2.5 取栈大小
//栈的大小
int StackSize(ST* ps)
{
assert(ps);
return ps->top;//注意是从0开始的
}
2.6 判断栈空
//判断栈是否为空
bool StackEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;//==0是真返回true;!=0是假返回false
}
2.7 栈的销毁
//栈的销毁
void StackDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->top = ps->capacity = 0;
}
三、简单的选择题题型
题型一
1.一个栈的初始状态为空。现将元素1、2、3、4、5、A、B、C、D、E依次入栈,然后再依次出栈,则元素出
栈的顺序是( )。
A 12345ABCDE
B EDCBA54321
C ABCDE12345
D 54321EDCBA
题型二:
2.若进栈序列为 1,2,3,4 ,进栈过程中可以出栈,则下列不可能的一个出栈序列是()
A 1,4,3,2
B 2,3,4,1
C 3,1,4,2
D 3,4,2,1
[解析] C的错误在于,出栈直接从3跳到1没有经过2