栈可以看做受限的顺序表,它的插入与删除只能在表尾进行,将表尾称为栈顶,表头称为栈底。不含元素的空表称为空栈。根据栈的定义可以知道栈的修改遵循后进先出的原则。
下面给出顺序栈的相关操作:
#include<stdio.h>
#include<malloc.h>
typedef int ElemType;
#define INIT_SIZE 10
#define INC_SIZE 5
typedef struct SeqStack //栈的结构体定义
{
ElemType *base;
ElemType top;
ElemType size;
}SeqStack;
void InitStack(SeqStack *s) //初始化
{
s->base = (ElemType *)malloc(sizeof(ElemType));
s->top = 0; //栈顶指向0
s->size = INIT_SIZE;
}
int IsEmpty(SeqStack s) //判断栈是否为空
{
return s.top = 0 ? 1 : 0; //将栈顶的值返回 若为0则表示为空栈
}
int IsFull(SeqStack s) //判断是否为满栈
{
return s.top>s.size ? 1 : 0; //依旧将栈顶的值返回 若大于栈的容量size 则表示栈已经满了
}
void Show(SeqStack s) //显示函数 将栈内的元素显示出来
{
int i;
for(i=s.top-1; i>0; i--) //利用循环 从栈顶元素开始依次输出打印
printf("%d ", s.base[i]);
printf("\n");
}
int Inc(SeqStack *s) //增加空间 当输入元素个数超过栈初始化时的容量是需要增加栈的空间
{
int newsize = s->size + INC_SIZE; //定义新的空间 它的大小等于原来栈的大小加上要开辟的空间大小
s->base = (ElemType*)realloc(s->base, sizeof(ElemType)*newsize); //利用realloc()函数动态开辟空间 在原来的空间里开辟sizeof大小的空间
if(s->base == NULL)
return 0;
else
{
s->size = newsize; //修改栈的大小
return 1;
}
}
void Push(SeqStack *s, ElemType x) //压栈操作
{
if(IsFull(*s) && Inc(s))
{
printf("栈已满且增加空间失败,不能进行进栈操作!\n");
return;
}
s->base[s->top] = x; //将要压入的数据赋给栈顶所指的空间
s->top++; //top上移
}
void Pop(SeqStack *s) //出栈操作
{
if(IsEmpty(*s))
{
printf("栈已空,无法进行出栈操作!\n");
return;
}
s->top--; //将栈顶下移
}
int Length(SeqStack s) //求栈的长度
{
return s.top-1; //返回栈顶的位置 由于栈的初始化里将栈顶置为0 所以在每次压栈操作结束后栈顶都会向上移动 故top在最后元素的上面
} //所以 将top-1就能得到栈的长度
void Clear(SeqStack *s) //清除操作
{
s->top = 0; //将top置零
}
void Destroy(SeqStack *s) //销毁
{
if(s->base != NULL)
{
free(s->base); //释放栈空间并置空
s->base = NULL;
}
s->top = 0; //栈顶top置零 大小置零
s->size = 0;
}
int GetTop(SeqStack *s, ElemType *x) //获取栈顶元素
{
if(IsEmpty(*s)) return 0;
*x = s->base[s->top-1];
return 1;
}