1、基本概念
- 栈:只允许在一端插入或删除操作的线性表
- 栈底(buttom):固定的,不允许进行插入和删除操作的另一端
- 栈顶(top):线性表允许插入和删除的一段
栈是线性表,只不过受到限制了,只允许在栈顶进行插入和删除操作,所以先入栈的后出栈
2、顺序栈
栈是线性表的特例,栈的顺序存储也是线性表顺序存储。栈的顺序存储结构叫做顺序栈,由于栈是受到限制的(只允许在栈顶进行插入和删除),所以顺序栈需要在顺序表是基础上修改点
/*
顺序栈的定义
*/
#define MaxSize 50 //定义栈中有多少个元素
typedef int ElemType;
typedef struct {
ElemType data[MaxSize];//存放栈中元素
int top; //栈顶指针
}SqStack;
- top值不能超过MaxSize
- 空栈的判断条件top==-1,初始值也是这个值,当没有元素时,top指向buttom后一个元素,满栈的判断条件top==MaxSize-1
2.1 基本操作
2.1.1 判空
/*
判断空
*/
bool StackEmpty(SqStack S) {
if (S.top == -1)
return true;
else
return false;
}
2.1.2 进栈
栈不满时,栈顶指针先加1,再送值到栈顶元素
/*
进栈
*/
bool Push(SqStack& S, ElemType x) {
if (S.top == MaxSize - 1)
return false;
S.data[++S.top] = x;
return true;
}
2.1.3 出栈
先判断栈是否为空,不为空,取栈顶元素,top减一
/*
出栈
*/
bool Pop(SqStack& S, ElemType& x) {
if (S.top == -1)
return false;
x = S.data[S.top];
S.top--;
return true;
}
2.1.4 读取栈顶元素
栈顶不为空,取栈顶元素
/*
读取栈顶元素
*/
bool GetTop(SqStack S, ElemType& x)
{
if (S.top == -1)
return false;
x = S.data[S.top];
return true;
}
3、共享栈
栈底位置相对不变的,可以让两个顺序栈共享一个一维数组,将两个栈的栈底分别设置在共享栈的两端,两个栈顶向共享空间的中间延伸,当一个栈存放数据少,一个栈存放数据多,可以考虑共享栈
typedef struct {
ElemType data[MaxSize]; //存放元素
int top1; //栈1栈顶
int top2; //栈2栈顶
}SqDoubleStack;
- 初始状态:top1=-1,top2=MaxSize,所以当top1=-1时表示栈1空,top2=MaxSize时,表示栈2空
- 栈满:当top1和top2相差1时,栈满,此时两个栈的栈顶紧挨着,没有空间存放数据了
- 出栈:top2加1,top1要减1
- 入栈:top1加1,top2减1
3.1基本操作
3.1.1 进栈
/*
进栈
stackNum:栈的序号
*/
bool Push(SqDoubleStack& S, ElemType x, int stackNum) {
if (S.top1 + 1 == S.top2)
return false; //栈满
if (stackNum == 1)
S.data[++S.top1] = x;
if (stackNum == 2)
S.data[++S.top2] = x;
return true;
}
4、链式栈
采用链式存储的栈称为链栈,链栈的优点是便于多个栈共享存储空间和提高其效率,并且不存在栈满溢出的情况,通常采用单链表实现,并规定所有操作都是在单链表的表头进行的
带头结点:
typedef struct SNode {
ElemType data; //数据域
struct SNode* next; //指针域
} SNode,*SLink; //链栈的结点
typedef struct LinkStack {
SLink top; //栈顶指针
int count; //链栈结点数
}LinkStack; //链栈
不带头结点:
typedef struct SNode {
ElemType data; //数据域
struct SNode* next; //指针域
} SNode,*SLink;
注意不带头结点和带头结点的链栈,在具体实现方面有所不同
扫描二维码关注公众号,回复:
9764273 查看本文章
- 可以将头指针当做栈顶
- 空栈的判断条件定为top==null
4.1 基本操作
4.1.1 进栈
/*
进栈
*/
bool Push(LinkStack *S, ElemType x) {
SLink p = (SLink)malloc(sizeof(SNode));
p->data = x;
p->next = S->top;
S->top = p;
S->count++;
return true;
}
4.1.2 出栈
/*
出栈
*/
bool Pop(LinkStack* S, ElemType& x) {
if (S->top == NULL)
return false;
x = S->top->data;
SLink p = S->top;
S->top = S->top->next;
free(p);
S->count--;
return true;
}