一.概念
栈是一种仅在表尾进行插入或者删除操作的线性表
。且表的首尾两端都有特殊的含义:表头我们一般称为栈底
,表尾(最后一个元素的位置)称为栈顶
,不含元素或者栈底=栈顶
的栈,我们称之为空栈
。
所以,栈是一种先进后出
的表结构。这种情况,和我们的火车调度站非常相似。
二.栈的结构定义
因为栈的内部储存结构,可以用顺序结构,也可以用链式结构,但在这部分储存方式与前面的线性表、单链表相似,所以本文采用顺序存储的方法来实现。
1.栈定义
对于一个栈,我们要定义三个部分,一个是base
作为我们基础的“容器”存放我们的数据,然后还得要有一个top
栈顶指针,来指向我们当前的栈顶元素,因为是顺序表,所以我们还得有一个maxlen
来储存base
的最大长度,以免越界。top
可以是一个整形,通过base+top
的方式,得到栈顶指针,当然,也可以直接将top
声明成和base
相同的类,然后存放栈顶的指针。因为本来就是顺序表,所以越简单越好,所以采用整形的方式去存储。
2.初始化栈
对于栈的初始化,我们只用申请一个默认长度的空间,赋值给base
,然后将maxlen
更新至我们初始化的长度,最后top=0
,也就是指向了base
。
3.销毁栈
直接free
掉我们的base
4.栈是否为空
我们直接判断top==0
5.栈长度
因为是顺序存储结构,所以并不需要去遍历整个表,直接返回top
,栈顶指针,就是我们的栈的长度了。
6.栈顶元素
如果栈不为空,那么返回*(base+top)
的值就行
7.入栈
我们只需要更新栈顶的指针位置,并赋上我们要压入的值,这样元素就入栈了。
当然,我们得判断base
的存储空间够不够,如果不够还需要realloc base
,以免造成越界。按照我的习惯,我喜欢入了栈后再检查并扩容,做好主准备。
8.出栈
返回当前栈顶指针指向的地址的值,然后将栈顶指针-1
。
三.代码实现
因为只要知道原理了,那么实现起来就比较简单,所以就不怎么添加注释了。
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define DEFAULT_LEN 20
#define EXTEND_LEN 5
typedef struct elemType{
int data;
}elemType;
typedef struct Stack{
elemType *base;
int top;
int maxlen;
}Stack;
Stack* StackInit(void);
int GetTop(Stack *S, elemType *elem);
int Push(Stack* S, elemType elem);
elemType Pop(Stack* S);
int IsEmpty(Stack *S);
int main()
{
Stack* s = StackInit();
elemType test;
test.data = 123;
Push(s,test);
test.data = 456;
Push(s,test);
test.data = 789;
Push(s,test);
while(IsEmpty(s) == 0)
{
printf("%d\n", Pop(s).data);
}
return 0;
}
Stack* StackInit(void)
{
Stack *S = (Stack*)malloc(sizeof(Stack));
if (S == NULL)
{
return ERROR;
}
S->base = (elemType *)malloc(sizeof(elemType)*DEFAULT_LEN);
S->top = 0;
S->maxlen = DEFAULT_LEN;
if (S->base != NULL)
{
return S;
}
else
{
exit(1);
}
}
int GetTop(Stack *S, elemType *elem)
{
if (S->base != NULL && S->top != 0)
{
elem = S->base + S->top;
return OK;
}
else
{
return ERROR;
}
}
int Push(Stack *S, elemType elem)
{
if (S->top < S->maxlen)
{
S->top += 1;
*(S->base+S->top) = elem;
if (S->top >= S->maxlen)
{
S->base = (elemType*)realloc(S->base, sizeof(elemType)*(S->maxlen + EXTEND_LEN));
if (S->base != NULL)
{
return OK;
}
else
{
exit(1);
}
}
}
else
{
return ERROR;
}
}
elemType Pop(Stack* S)
{
elemType *elem;
if (S->top > 0)
{
elem = S->base+S->top;
S->top -= 1;
return *elem;
}
else
{
exit(2);
}
}
int IsEmpty(Stack *S)
{
if (S->top > 0)
{
return 0;
}
else
{
return 1;
}
}