前言
1、理解顺序栈的定义,以及对元素的进栈,出栈,读栈顶元素
2、理解链栈的定义,以及对元素的进栈,出栈,读栈顶元素
提示:以下是本篇文章正文内容,下面案例可供参考
一、栈:只能在一端进行插入删除操作的线性表
- 栈顶:可以进行插入删除操作
- 栈底:不能进行任何操作
- 特点:先进后出(FILO)
1.1 顺序栈:
#define MaxSize 10 //定义栈中元素的个数
typedef struct {
ElemType data[MaxSize]; //存放元素
int top; //定义栈顶指针
}SqStack;
//栈顶指针:S.top,初始值为-1,栈顶元素:S.data[S.top]
//栈空条件:S.top==-1,栈满条件:S.top==MaxSize-1,栈长:S.top-1
//初始化
void InitStack(SqStack &S){
S.top=-1; //初始化栈顶指针
}
//判断栈是否为空
Bool StackIsEmpty(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;
S.data[S.top]=x;
//S.data[++S,top]=x; //指针先+1,在入栈
return true;
}
//出栈
Bool Pop(SqStack &s,ElemType &x){
if(S.top==-1) //栈空报错
return false;
S.data[S.top]=x;
S.top=S.top-1;
//S.data[S.top--]=x; //先出栈,指针再-1
return true;
}
//读取栈顶元素
Bool Pop(SqStack &s,ElemType &x){
if(S.top==-1) //栈空报错
return false;
x=S.data[S.top]; //x获取栈顶元素的值
return true;
}
当栈顶指针初始化为S.top=0时:
//当S.top的初始值为0时,栈空条件:s.top==0,栈满条件:S.top==MaxSize,栈长:S.top
//初始化
void InitStack(SqStack &S){
S.top=0; //初始化栈顶指针
}
//判断栈是否为空
Bool StackIsEmpty(SqStack &s){
if(S.top==0)
return true; //栈空
else
return false; //栈不空
}
//进栈
Bool Push(SqStack &s,Elemtype x){
if(S.top==MaxSize) //栈满,报错
return false;
S.data[S.top]=x;
S.top=S.top+1;
//S.data[S,top++]=x; //先入栈,再指针+1
return true;
}
//出栈
Bool Pop(SqStack &s,ElemType &x){
if(S.top==0) //栈空报错
return false;
S.top=S.top-1;
s.data[s.top]=x;
//S.data[--S.top]=x; //指针先-1,在出栈
return true;
}
//读取栈顶元素
Bool Pop(SqStack &s,ElemType &x){
if(S.top==0) //栈空报错
return false;
x=S.data[S.top]; //x获取栈顶元素的值
return true;
}
1.2 链栈:
不带头结点的链表
//链栈结点的定义
typedef struct LinkLNode{
ElemType data; //数据域
struct LinkLNode *next; //指针域
}LinkLNode; //链栈结点定义
//不带头结点链栈的初始化
void initLinkStack(LinkLNode *&L){ //需要改变栈的内容,用引用型
L=(LinkLNode*)malloc(sizeof(LinkLNode)); //定义一个新的结点
L->data=NULL; //不建头结点,此结点就是第一个结点
}
//判断栈空代码
bool isEmpty(LinkLNode *L){ //判断是否为空
if(L->data==NULL)
return true;
else
return false;
}
//进栈
bool Push(LinkLNode *L,ElemType x){
LinkLNode *p;
p=(LinkLNode*)malloc(sizeof(LinkLNode)); //进栈元素申请新的结点
p->next=NULL; //可以避免一些错误
/*不带头结点链表的头插法*/
L->data=x;
p->next=L;
L=p;
return true;
}
//出栈
bool Pop(LinkLNode *L,ElemType &x){ //获取栈顶元素的值,使用引用型
LinKLNode *p;
if(L->data==NULL)
return false;
/*不带头结点链表的删除操作*/
p=L
x=p->data;
L=p->next;
free(p);
return true;
}
带头结点:
//链栈结点的定义
typedef struct LinkLNode{
ElemType data; //数据域
struct LinkLNode *next; //指针域
}LinkLNode; //链栈结点定义
//带头结点链表的初始化
void initLinkStack(LinkLNode *&L){ //需要改变栈的内容,用引用型
L=(LinkLNode*)malloc(sizeof(LinkLNode)); //定义一个新的结点
L->next=NULL; //此节点作为头结点,判空条件L->next==NULL
}
//判断栈空代码
bool isEmpty(LinkLNode *L){ //判断是否为空
if(L->==NULL)
return true;
else
return false;
}
//进栈
bool Push(LinkLNode *L,ElemType x){
LinkLNode *p;
p=(LinkLNode*)malloc(sizeof(LinkLNode)); //定义一个新结点
p->next=NULL;
/*带头结点的头插法*/
p->data=x;
p->next=L->next;
L->next=p;
return true;
}
//出栈
bool Pop(LinkLNode *L,ElemType &x){
LinkLNode *p;
if(L->next==NULL) //栈空,不能进行删除操作
return false;
/*带头结点的删除操作*/
p=L->next;
x=p->data;
L->next=p->next;
free(p);
return true;
}