一、栈的基本概念
栈(Stack)是限定仅在表尾进行插入和删除操作的线性表
1.把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom)
2.==不含任何数据元素的栈称为空栈。
3.栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构。
二、栈的顺序存储结构
1.顺序栈的基本操作
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAXSIZE 50
typedef int ElemType;
typedef struct Node
{
ElemType data[MAXSIZE];
int top; //栈顶指针
}SqStack;
初始化栈
void InitStack(SqStack* S)
{
S->top = -1;
}
进栈
bool Push(SqStack* S,ElemType e)
{
if (S->top == MAXSIZE - 1) //栈满
return false;
S->data[++(S->top)] = e; //栈顶指针先加1,移动到下一位置,再赋值给栈顶空间
return true;
}
出栈
bool Pop(SqStack* S, ElemType* e)
{
if (S->top == -1) //栈空
return false;
*e = S->data[(S->top)--]; //将要删除的栈顶元素先赋值给e,栈顶指针再减1
}
2.两栈共享空间
对于两栈共享空间,数组有两个端点,两个栈有两个栈底,让一个栈底为数组始端,即下标为0处,另一个栈为数组的末端,即下标为MAXSIZE-1处,两个栈如果增加元素,就是两端点向中间延伸
typedef struct
{
ElemType data[MAXSIZE]
int top1; //栈1栈顶指针
int top2; //栈2栈顶指针
}SqDbStack;
初始化共享栈
void InitSqDbStack(SqDbStack* S)
{
S->top1 = -1;
S->top2 = MAXSIZE;
}
进栈
对于共享栈的push方法,除了要插入元素值参数外,还需要有一个判断是栈1还是栈2的栈号参数stackNumber
bool Push(SqDbStack *S,ElemType e,int stackNumber)
{
if(S->top1+1==S->top2) //栈满
return false;
if(stackNumber==1) //栈1有元素进栈
S->data[++S->top1] = e;
if(stackNumber==2) //栈2有元素进栈
S->data[++S->top2] = e;
return true;
出栈
/*若栈不空,则删除S的栈顶元素,用e返回其值*/
bool Pop(SqDbStack* S,ElemType *e,int stackNumber)
{
if(stackNumber==1)
{
if(S->top==-1) //说明栈1是空栈
return false
*e = S->data[S->top1--]; //将栈1的栈顶元素出栈
}
else if(stackNumber==2)
{
if(S->top2==MAXSIZE) //说明栈2是空栈
return false;
*e = S->data[S->top2--];
}
return true;
}
使用这样的数据结构,通常都是当两个栈的空间需求有相反关系时,也就是一个栈增长时另一个栈缩短的清空
三、栈的链式存储结构
通常对于链栈来说是不需要头结点的
typedef struct StackNode {
ElemType data;
struct StackNode* next;
}StackNode,*LinkStackPtr;
typedef struct LinkStack{
LinkStackPtr top; //栈顶指针
int count;
}LinkStack;
1.初始化栈
void InitLinkStack(LinkStack* S)
{
S->top = NULL;
S->count = 0;
}
2.进栈
bool Push(LinkStack* S, ElemType e)
{
LinkStackPtr p = (LinkStackPtr)malloc(sizeof(StackNode));
p->data = e;
p->next = S->top;
S->top = p;
S->count++;
return true;
}
3.出栈
bool Pop(SqDbStack* S,ElemType* e)
{
LinkStackPtr p;
if(StackEmpty(*S)) //判断是否为空
return false;
*e = S->top->data;
p = S->top; //将栈顶结点赋值给p
S->top = S->top->next; //栈顶指针下移一位,指向后一结点
free(p);
S->count--;
return true;