目录
一.栈的概念和结构
栈:是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素的操作。进行数据插入和删除操作的一端 称为栈顶,另一端为栈底。栈中的数据元素遵守 后进先出 LIFO (Last In First Out)的原则。
栈可以用数组来实现,也可以用链表来实现,相对而言数组栈会更优一点。(数组栈在尾上删除数据会更容易一点,代价小)
数组实现栈:
如果用链表来实现栈,如果让链表的头作栈顶,就是头插头删。(可以设计成单向链表)
如果让链表的尾做栈顶,就是尾插尾删。(最好设计成双向链表)
二.栈的各个函数接口及实现
1.动态数组栈的结构体定义
a是指向数组的指针;top表示栈顶;capacity表示数组的实际容量。
(我们这里实现的是一个动态的数组栈,空间不够时,可以动态增容)
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top;//栈顶
int capacity;//容量
}ST;
2.栈的初始化
初始化:这里把top初始化成 0 ,则top就代表栈顶的下一个数据的下标位置。
(这个时候的top也代表了栈内数据的个数)
如果这里把top初始化成 -1 ,则top就代表栈顶数据的下标位置。
void StackInit(ST* ps)//初始化栈
{
assert(ps);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
3.栈的销毁
释放a指针所指向的连续的空间,把a指针置空,把top和capacity置0.
void StackDestroy(ST* ps)//销毁栈
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
4.在栈顶插入数据(入栈)
压栈:栈的插入操作叫做进栈 / 压栈 / 入栈, 入数据在栈顶 。对于数组进行插入操作时,需要注意的是:要首先检查数组空间够不够,不够了就要进行扩容操作;空间够的话,就可以进行插入操作了。
void StackPush(ST* ps, STDataType x)//增加,入栈
{
assert(ps);
if (ps->top == ps->capacity)
{
int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
STDataType* tmp = (STDataType*)realloc(ps->a,sizeof(STDataType)*newcapacity);
if (tmp == NULL)
{
printf("realloc fail\n");
exit(-1);
}
ps->a = tmp;
ps->capacity = newcapacity;
}
ps->a[ps->top] = x;
ps->top++;
}
5.删除栈顶数据(出栈)
出栈:栈的删除操作叫做出栈。 出数据也在栈顶 。对于删除操作,需要注意的是:如果栈已经为空(top==0)的时候,就不能进行删除操作了。如果栈不为空(top!=0)时,让top--,就完成了数组栈的删除操作了。
bool StackEmpty(ST* ps)//判断栈是否为空
{
assert(ps);
return ps->top == 0;
/*if (ps->top == 0)
return true;
else
return false;*/
}
void StackPop(ST* ps)//删除,出栈
{
assert(ps);
assert(!StackEmpty(ps));//判断栈是否为空
ps->top--;
}
6.取出栈顶的数据
首先栈不为空时,才有栈顶数据,所以要先判断栈是否为空。
栈不为空时,取出栈顶数据( ps->a[ps->top-1] )就可以了。
bool StackEmpty(ST* ps)//判断栈是否为空
{
assert(ps);
return ps->top == 0;
/*if (ps->top == 0)
return true;
else
return false;*/
}
STDataType StackTop(ST* ps)//栈顶的数据,获取栈顶数据
{
assert(ps);
assert(!StackEmpty(ps));//判断栈是否为空
return ps->a[ps->top-1];
}
7.栈内的元素个数
top的值就是栈内的元素个数了。
int StackSize(ST* ps)//栈内数据的多少,获取栈中有效元素的个数
{
assert(ps);
return ps->top;
}
8.判断栈的是否为空
判断栈是否为空:如果top==0,则栈为空; 如果top!=0, 则栈不为空。
bool StackEmpty(ST* ps)//判断栈是否为空
{
assert(ps);
return ps->top == 0;
/*if (ps->top == 0)
return true;
else
return false;*/
}
三.关于栈的选择题
选择题1:
1. 若进栈序列为 1,2,3,4 ,进栈过程中可以出栈,则下列不可能的一个出栈序列是( C )A 1,4,3,2B 2,3,4,1C 3,1,4,2D 3,4,2,1
选择题2:
2. 一个栈的初始状态为空。现将元素 1 、 2 、 3 、 4 、 5 、 A 、 B 、 C 、 D 、 E 依次入栈,然后再依次出栈,则元素出栈的顺序是( B )。A 12345ABCDEB EDCBA54321C ABCDE12345D 54321EDCBA解:题目中说是依次入栈,就是都入栈以后才开始依次出栈,所以就是很常规的那种,栈遵 循后进先出的规则。 所以出栈顺序就是入栈顺序的逆序。