1. 栈的概念以及结构
栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/插栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶。
总:
栈顶(top):线性表允许进行插入删除的那一端
栈底(bottom):固定的,不允许进行插入和删除的另一端
空栈:不含任何元素的空表
2.栈的功能以及实现
栈的实现一般可以使用数组或者链表来实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小
这里定长的静态栈的结构,实现中一般不实用
//静态栈
typedef int STDataType;
#define N 10
typedef struct Stack
{
STDataType a[N];
int top;
}Stack;
所以我们主要实现下面的支持动态增长的栈
//支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
STDataType* a;
int top; //栈顶
int capacity; //容量
}Stack;
栈所需要实现的一些功能
//栈初始化
void STInit(ST* ps);
//清空栈
void STDestroy(ST* ps);
//插入栈
void STPush(ST* ps);
//删除栈元素
void STPop(ST* ps);
//查看栈的大小
int STSize(ST* ps);
//查看栈中有没有元素
bool STEmpty(ST* ps);
//输出栈顶元素
STDataType STTop(ST* ps);
->1. 栈初始化
void STInit(ST* ps)
{
assert(ps);
ps->a = (ST*)malloc(sizeof(ST) * CAPACITY__SIZE);
if (NULL == ps->a)
{
perror("STInit::malloc");
return;
}
//压栈元素的下一个位置
ps->top = 0;
ps->capacity = CAPACITY__SIZE;
}
->2. 清空栈
//清空栈
void STDestroy(ST* ps)
{
free(ps->a);
ps->a = NULL;
ps->top = 0;
ps->capacity = 0;
}
->3. 插入栈
//插入栈
void STPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
ST* Expand = (ST*)realloc(ps->a,sizeof(ST) * ps->capacity * CAPACITY__SIZE);
if (NULL == Expand)
{
perror("STPop::malloc");
exit(-1);
}
ps->a = Expand;
ps->capacity *= CAPACITY__SIZE;
}
ps->a[ps->top++] = x;
}
->4. 删除栈元素
//删除栈元素
void STPop(ST* ps)
{
assert(ps);
assert(!STEmpty);
ps->top--;
}
->5. 查看栈的大小
//查看栈的大小
int STSize(ST* ps)
{
return ps->top;
}
->6. 查看栈中有没有元素
//查看栈中有没有元素
bool STEmpty(ST* ps)
{
return ps->top == 0;
}
->7.输出栈顶元素
//输出栈顶元素
STDataType STTop(ST* ps)
{
assert(ps);
assert(!STEmpty);
return ps->a[ps->top - 1];
}
整合以上我们来实现栈,下面是实现栈的完整代码
Stack.h
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
//动态栈
#define CAPACITY__SIZE 4
typedef int STDataType;
typedef struct Stack
{
int* a;
int top;
int capacity;
}ST;
//栈初始化
void STInit(ST* ps);
//清空栈
void STDestroy(ST* ps);
//插入栈
void STPush(ST* ps, STDataType x);
//删除栈元素
void STPop(ST* ps);
//查看栈的大小
int STSize(ST* ps);
//查看栈中有没有元素
bool STEmpty(ST* ps);
//输出栈顶元素
STDataType STTop(ST* ps);
Stack.c
#include "Stack.h"
void STInit(ST* ps)
{
assert(ps);
ps->a = (STDataType*)malloc(sizeof(STDataType) * CAPACITY__SIZE);
if (NULL == ps->a)
{
perror("STInit::malloc");
return;
}
//压栈元素的下一个位置
ps->top = 0;
ps->capacity = CAPACITY__SIZE;
}
//清空栈
void STDestroy(ST* ps)
{
free(ps->a);
ps->a = NULL;
ps->top = 0;
ps->capacity = 0;
}
//插入栈
void STPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
STDataType* Expand = (STDataType*)realloc(ps->a,sizeof(STDataType) * ps->capacity * CAPACITY__SIZE);
if (NULL == Expand)
{
perror("STPop::malloc");
exit(-1);
}
ps->a = Expand;
ps->capacity *= CAPACITY__SIZE;
}
ps->a[ps->top++] = x;
}
//删除栈元素
void STPop(ST* ps)
{
assert(ps);
assert(!STEmpty(ps));
ps->top--;
}
//查看栈的大小
int STSize(ST* ps)
{
return ps->top;
}
//查看栈中有没有元素
bool STEmpty(ST* ps)
{
return ps->top == 0;
}
//输出栈顶元素
STDataType STTop(ST* ps)
{
assert(ps);
assert(!STEmpty(ps));
return ps->a[ps->top - 1];
}
test.c
#include "Stack.h"
int main()
{
ST Stack;
STInit(&Stack);
STPush(&Stack, 1);
STPush(&Stack, 2);
STPush(&Stack, 3);
STPush(&Stack, 4);
STPush(&Stack, 5);
/*while (!STEmpty(&Stack))
{
printf("%d->", Stack.a[--Stack.top]);
}
printf("NULL\n");*/
while (!STEmpty(&Stack))
{
printf("%d ", STTop(&Stack));
STPop(&Stack);
}
printf("\n");
STDestroy(&Stack);
return 0;
}
测试结果: