1.栈的基本概念
栈(Stack)是只允许在一端进行插入或删除操作的线性表
逻辑结构:与普通线性表相同
数据的运算:插入,删除操作有区别
重要术语:栈顶,栈底,空栈
进栈顺序:a1->a2->a3->a4->a5
出栈顺序:a5->a4->a3->a2->a1
特点:后进先出 Last In First Out (LIFO)
2.栈的基本操作
InitStack(&S):初始化栈。构造一个空栈S,分配内存空间。
DestroyStack(&L):销毁栈。销毁并释放栈S所占用的内存空间。
Push(&S,x):进栈,若栈S未满,则将x加入使之成为新栈顶。
Pop(&S,&x):出栈,若栈S非空,则弹出栈顶元素,并用x返回。
GetTop(S,&x):读栈顶元素。若栈S非空,则用x返回栈顶元素。
StackEmpty(S):判断栈S是否为空。为空返回true,非空返回false。
3.栈的顺序存储
定义顺序栈:
#define MaxSize 10 //定义栈中元素的最大个数
typedef struct{
ElemType data[MaxSize];//静态数组存放栈中元素
int top; //栈顶指针
}SqStack;
//初始化栈
void InitStack(SqStack &S){
S.top=-1; //初始化栈顶指针
}
void testStack() {
SqStack S; //声明一个顺序栈(分配空间)
InitStack(S);
//后续操作。。。
}
判断栈空:
bool StackEmpty(SqStack S){
if(S.top==-1) //栈空
return true;
else //不空
return false;
}
进栈操作:
bool Push(SqStack &S,ElemType x){
if(S.top==MaxSize-1) //栈满,报错
return false;
S.top = S.top + 1; //指针先加1
S.data[S.top]=x; //新元素入栈
return true;
}
出栈操作:
bool Pop(SqStack &S,ElemType &x){//x加上了引用符号,即出栈操作的调用者首先在自己的函数里定义变量x,该变量存放在内存中。所以在本算法里操作的x和函数调用者定义的x是同一份数据,而不是它的复制品。
if(S.top==-1) //判断栈是否为空
return false;
x=S.data[S.top]; //把栈顶指针指向的元素赋值给变量x
S.top = S.top - 1; //指针再减1
return true;
}
删除结束后,数据还是残留在内存中,只是逻辑上被删除了。
读取栈顶元素:
bool GetTop(SqStack S,Elemtype &x){
if(S.top==-1) //栈空,报错
return false;
x=S.data[S.top]; //x记录栈顶元素
return true;
}
顺序栈缺点:栈的大小不可变
4.共享栈
共享栈:两个栈共享同一片空间
定义共享栈:
#define MaxSize 10 //定义栈中元素的最大个数
typedef struct{
ElemType data[MaxSize];//静态数组存放栈中元素
int top0; //0号栈栈顶指针
int top1; //1号栈栈顶指针
}SqStack;
//初始化栈
void InitStack(ShStack &S){
S.top0=-1; //初始化栈顶指针
S.top1=MaxSize;
}
栈满的条件:top0 + 1 == top1
5.链栈
链栈:用链式存储方式实现的栈
链栈的定义:
typedef struct Linknode{
ElemType data; //数据域
struct Linknode *next; //指针域
}*LiStack; //栈类型定义