建立文件
新建三个文件:
Stack.h:函数声明
Stack.c:函数实现
main.c:函数调用
栈的设定
先入后出,类似弹夹
使用数组的形式进行实现,尾部做栈顶,尾插和尾删作为压栈和出栈
定义结构体
Stack.h 中写入:
typedef int STDatatype;
typedef struct Stack
{
STDatatype* a;//存放数据
int top;//记录当前数据的个数
int capacity;//当前空间的最大容量
}ST;
函数调用的实现
主函数依旧使用do-while、switch语句,实现重复使用和选项操作
流程
进入程序 --> 栈的初始化(第一个函数) --> 进入循环 --> 打印菜单(第二个函数) --> 用户进行选择 --> 进入switch -->
case 1:尾插数据,压栈(第三个函数)
case 2:尾删数据,出栈(第四个函数)
case 3:打印数据(第五个函数)
case 0:退出程序,销毁栈(第六个函数)
进行函数声明
Stack.h 中写入:
void StackInit(ST* ps);//初始化
void menu();//菜单
void StackPush(ST* ps);//压栈
void StackPop(ST* ps);//出栈
void StackPrint(ST* ps);//打印
void StackDestory(ST* ps);//销毁
完成主函数
创建枚举常量
Stack.h 中写入:
enum Option
{
Exit,
Push,
Pop,
Print
};
完成主函数
main.c中写入:
int main()
{
int input = 0;
ST st;
StackInit(&st);
do
{
menu();
scanf("%d", &input);
switch (input)
{
case Push:
StackPush(&st);
break;
case Pop:
StackPop(&st);
break;
case Print:
StackPrint(&st);
break;
case Exit:
StackDestory(&st);
printf("bye bey!\n");
break;
default:
printf("Seleect error, Please Select Again!\n");
break;
}
} while (input);
return 0;
}
StackInit的实现
初始化时开辟 4 个 STDatatype 的空间,top 为 0,capacity 为 4
Stack.c 中写入:
void StackInit(ST* ps)//初始化
{
assert(ps);
ps->a = (STDatatype*)malloc(sizeof(STDatatype) * 4);
if (ps->a == NULL)
{
perror("StackInit\n");
exit(-1);
}
ps->top = 0;
ps->capacity = 4;
}
menu的实现
Stack.c 中写入:
void menu()
{
printf("--------------------------------------\n");
printf("********** 1、Push 2、Pop **********\n");
printf("********** 3、Print 0、Exit **********\n");
printf("--------------------------------------\n");
printf("Please Select:");
}
StackPush的实现
StackPush的实现
在数组中尾插数据,将下标为 top 的位置放入数据 x,然后 top++
void StackPush(ST* ps)//栈顶插入
{
assert(ps);
BuyStack(ps);//当空间不够时,开辟新空间
STDatatype x = 0;
printf("请输入你要插入的数据:");
scanf("%d", &x);
*((ps->a) + ps->top) = x;
ps->top++;
printf("压栈成功!\n");
}
用到了一个新函数 - BuyStack
BuyStack的实现
当空间不够时,开辟新空间
void BuyStack(ST* ps)//开辟空间
{
assert(ps);
if (ps->top == ps->capacity)
{
STDatatype* tmp = (STDatatype*)realloc(ps->a, ps->capacity * 2 * sizeof(STDatatype));
if (tmp == NULL)
{
perror("BuyStack\n");
exit(-1);
}
ps->a = tmp;//更新地址
ps->capacity *= 2;
}
}
StackPop的实现
void StackPop(ST* ps)//栈顶删除
{
assert(ps);
if (ps->top <= 0)//栈为空
{
printf("Stack is NULL!\n");
return;
}
ps->top--;
}
StackPrint的实现
StackPrint的实现
由于栈的特殊性,打印出来的数据的顺序是从栈顶到栈底排列的
void StackPrint(ST* ps)
{
assert(ps);
ST ps1 = *ps;//不能直接使用ps,这会改变原栈的数据
if ((&ps1)->top <= 0)//栈为空
{
printf("Stack is NULL!\n");
return;
}
while (!StackEmpty(&ps1))
{
printf("%d ", StackTop(&ps1));
StackPop(&ps1);
}
printf("\n");
}
用到了两个新函数
StackEmpty:判断栈是否为空
StackTop:返还栈顶数据
StackEmpty的实现
判断 top 就行
bool StackEmpty(ST* ps)//判断是否为空
{
assert(ps);
return ps->top == 0;
}
StackTop的实现
STDatatype StackTop(ST* ps)//返回栈顶数据
{
assert(ps);
if (ps->top <= 0)
{
printf("Stack is NULL!\n");
exit(-1);
}
return ps->a[ps->top - 1];
}
StackDestory的实现
free 加 置空
void StackDestory(ST* ps)//销毁
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->top = ps->capacity = 0;
}
栈除了用数组实现,也可以用链表实现,只不过数组更加高效一点