定义:
栈(stack)是限定在表的一端进行插入和删除运算的线性表,通常将插入、删除的一端称为栈顶(top),另一端称为栈底。不含元素的空表称为空栈。
特点:
- 后进先出(Last In First Out)的线性表,简称
LIFO
表
栈的顺序存储结构和基本运算
栈的顺序存储结构称为顺序栈。类似顺序表的定义,顺序栈也是用数组实现的。因为栈底位置是固定不变的,栈顶位置随着进栈和出栈操作而变化的,因此用一个整形量top来表示栈顶位置,通常称top为栈顶指针。
顺序栈SeqStack
定义如下:
#define StackSize 100 //栈大小
typedef char DataType;
typedef struct {
DataType data[StackSize]; //用数组存放结点
int top; //表示栈顶指针
}SeqStack;
SeqStack S;
S.top<0表示空栈,S.top = StackSize - 1 表示栈满。
当栈满时再做进栈运算必定产生空间溢出,简称上溢
,当栈空时再做退栈运算也会产生溢出,简称下溢
。
顺序栈基本运算
#include "stdio.h"
#include "stdlib.h"
#define StackSize 100 //栈大小
typedef char DataType;
typedef struct {
DataType data[StackSize]; //用数组存放结点
int top; //表示栈顶指针
}SeqStack;
SeqStack S;
/*
置空栈
S.top<0表示空栈
*/
void InitStack(SeqStack *S){
S->top = -1;
}
/*
判断栈空
*/
int StackEmpty(SeqStack *S){
return S->top == -1;
}
/*
判断栈满
*/
int StackFull(SeqStack *S){
return S->top == StackSize-1;
}
/*
进栈(入栈)
*/
void Push(SeqStack *S, DataType x){
if (StackFull(S)){
printf("栈满\n");
}
else{
S->top = S->top + 1; //栈顶指针加1
S->data[S->top] = x; //将X入栈
}
}
/*
退栈(出栈)
*/
DataType Pop(SeqStack *S){
if (StackEmpty(S))
{
printf("空栈\n");
exit(0);
}
else
{
return S->data[S->top--]; //返回栈顶元素并且栈顶指针减1
}
}
/*
去栈顶元素(不改变栈顶指针)
*/
DataType GetTop(SeqStack *S){
if (StackEmpty(S))
{
printf("栈满\n");
exit(0);
}
else
{
return S->data[S->top];
}
}
栈的链式存储结构及运算
由于顺序存储分配固定的空间会产生的溢出和空间浪费的问题,可以采用链式存储结构来存储栈。
栈的链式存储称为链栈
,因为是受限的单链表,插入和删除操作都限制在表头(栈顶)位置,因此不需要设置头结点,将单链表头指针head改为栈顶指针top即可。
链式栈LinkStack
结构如下:
typedef int DataType;
typedef struct stacknode
{
DataType data;
struct stacknode * next;
}StackNode;
typedef StackNode * LinkStack;
LinkStack top;
链栈的基本运算
/*
判断栈空
*/
int StackEmpty(LinkStack top){
return top == NULL;
}
/*
进栈
将新元素插入栈顶
*/
LinkStack Push(LinkStack top,DataType x){
StackNode * p;
p = (StackNode *)malloc(sizeof(StackNode)); //申请新结点
p->data = x; //新结点赋值
p->next = top; //将新结点插入到栈顶
top = p; //是top指向栈顶
return top; //返回栈顶新指针
}
/*
退栈(出栈)
*/
LinkStack Pop(LinkStack top,DataType *x){
StackNode * p = top; //保存栈顶指针
if (StackEmpty(top))
{
printf("栈为空\n");
exit(0);
}
else
{
*x = p->data; //保存删除结点的值
top = p->next; //栈顶指向下一个结点
free(p); //释放删除结点
return top; //返回新结点
}
}
DataType GetTop(LinkStack top){
if (StackEmpty(top))
{
printf("栈为空\n");
exit(0);
}
else
{
return top->data;
}
}