王道数据结构----顺序栈的实现(C语言)
一:栈的定义和特点
1:栈的定义
栈是限定仅在表尾进行插入或者删除操作的线性表。
表尾端成为栈顶
表头端称为栈底
2:结构图
3:特点
先进后出,后进先出(LIFO,Last In First Out)
4:栈的存储
栈的存储方式有两种:顺序栈和链栈,即栈的顺序存储和链式存储。
采用顺序存储的栈称为顺序栈,它利用一组地址连续的存储单元存放自栈底到栈顶的元素,同时附设一个指针(top)指示当前栈顶的位置。
采用链式存储的栈称为链栈,链栈便于多个栈共享存储空间和提高其效率,且不存在栈满上溢的情况。通常采用单链表实现,并且所有操作都是在单链表的表头进行的。
二:顺序栈
顺序栈是指利用顺序存储结构实现的栈。利用一组地址连续的存储单元一次存放自栈底带栈顶的数据元素,以及设指针top指示栈顶元素在顺序栈中的位置。
通常情况下top=-1或者top=0两种情况表示栈空。(具体情况具体对待)
基本操作:
- InitStack(&S) //构建一个空栈
- DestoryStack(&S) //销毁已经存在的栈
- ClearStack(&S) //清空已经存在的栈
- StackEmpty(S) //判断栈是否尾空
- StackLength(S) //返回栈的元素个数(栈的长度)
- GetTops(S) //返回栈顶元素(栈已存在且非空)
- Push(&S,e) //插入元素为e的新的栈顶元素
- StackTraverse(S) //从栈底到栈顶依次队每个数据元素进行访问
2.1:栈的顺序存储–结构体
typedef int ElemType;
#define MaxSize 10 //定义栈中的最大元素个数
typedef struct SeqStack{
int top; //栈顶指针
ElemType data[MaxSize]; //定义一个静态数组用来存放栈中的元素
}SeqStack; //这里的SeqStack等价于 typedef struct SeqStack SeqStack;
2.2:顺序表的初始化和判空’
栈非空时,top指针始终指向栈顶元素的上一个位置
初始化算法步骤:
- 初始化栈顶指针(判空条件S->top = -1;)
判空算法步骤:
- S.top == -1表示栈空
代码实现
//初始化
void InitStack(SeqStack *S){
S->top=-1; //初始化栈顶指针
}
//判空
int StackEmpty(SeqStack S){
if(S.top == -1) //S.top == -1,说明栈中没有元素
return 1;
else
return 0;
}
2.3:顺序表的入栈出栈
入栈算法步骤:
- 判断栈是否为空(栈满条件S.top==MaxSize-1)
- 将新元素压入栈顶,top++
代码实现
//入栈操作
int Push(SeqStack *S,ElemType e){
if(S->top==MaxSize-1){ //栈满条件S.top==MaxSize-1
return 0;
}
S->top++; //top指针加一
S->data[S->top]=e; //将新元素入栈
//上面两行代码等价与 S->data[++S->top]=e
return 1;
}
出栈算法步骤:
- 判断栈是否为空(栈满条件S.top==MaxSize-1)
- top–,栈顶元素出栈
int Pop(SeqStack S,ElemType *elemType){
if(S.top == -1){ //S.top == -1,说明栈中没有元素
return 0;
}
elemType=S.data[S.top];
S.top--;
//上面两行代码等价与 *elemType=S->data[S->top--]
return elemType;
}
2.4:取栈顶元素
算法步骤:
- 判断栈是否为空
- 直接返回栈顶元素
代码实现
//取栈顶元素
int GetTop(SeqStack S){
if(S.top==-1) //判断栈是否为空
return 0;
return S.data[S.top];
}
2.5:打印栈中的所有元素
算法步骤:
- 判断栈中的元素是否是空的
- 然后利用GetTop()函数和Pop()函数循环打印出所有栈中的元素。
代码实现
//打印栈中的所有元素
int PrintStack(SeqStack S){
if(S.top==-1){ //判断栈中的元素是否是空的
return 0;
}
ElemType X; //用与保存出栈和读栈顶元素返回的变量的值
int count = S.top;
for(int i = 0;i <= count;i++)//循环打印
{
printf("top = %d\n",i);
printf("栈顶元素 = %d\n",GetTop(S));
Pop(&S,&X);
printf("弹出的元素 = %d\n",X);
printf("--------------------\n");
}
}
三:完整代码
#include "stdio.h"
typedef int ElemType;
#define MaxSize 10 //定义栈中的最大元素个数
typedef struct SeqStack{
int top; //栈顶指针
ElemType data[MaxSize]; //定义一个静态数组用来存放栈中的元素
}SeqStack; //这里的SeqStack等价于 typedef struct SeqStack SeqStack;
//初始化
void InitStack(SeqStack *S){
S->top=-1; //初始化栈顶指针
}
//判空
int StackEmpty(SeqStack S){
if(S.top == -1) //S.top == -1,说明栈中没有元素
return 1;
else
return 0;
}
//入栈操作
int Push(SeqStack *S,ElemType e){
if(S->top==MaxSize-1){ //栈满条件S.top==MaxSize-1
return 0;
}
S->top++; //top指针加一
S->data[S->top]=e; //将新元素入栈
//上面两行代码等价与 S->data[++S->top]=e
return 1;
}
//出栈操作
int Pop(SeqStack *S,ElemType *elemType){
if(S->top == -1){ //S.top == -1,说明栈中没有元素
return 0;
}
*elemType=S->data[S->top];
S->top--;
//上面两行代码等价与 *elemType=S->data[S->top--]
return elemType;
}
//取栈顶元素
int GetTop(SeqStack S){
if(S.top==-1) //判断栈是否为空
return 0;
return S.data[S.top];
}
//打印栈中的所有元素
int PrintStack(SeqStack S){
if(S.top==-1){ //判断栈中的元素是否是空的
return 0;
}
ElemType X; //用与保存出栈和读栈顶元素返回的变量的值
int count = S.top;
for(int i = 0;i <= count;i++)//循环打印
{
printf("top = %d\n",i);
printf("栈顶元素 = %d\n",GetTop(S));
Pop(&S,&X);
printf("弹出的元素 = %d\n",X);
printf("--------------------\n");
}
}
int main(){
SeqStack S;
InitStack(&S);
Push(&S,1);
Push(&S,2);
Push(&S,3);
Push(&S,4);
Push(&S,5);
Push(&S,6);
PrintStack(S);
return 0;
}