栈的简单介绍
关于栈的性质咳咳
栈:栈是一种特殊的线性表,其中只让在一端插入和删除元素。
后进先出
进行插入删除的那一端叫栈顶,另一端叫栈底
我们实现的栈是基于一个动态顺序表的的栈,会实现栈的 入栈,出栈,获取栈顶元素,获取栈中元素个数,判断栈是否为空(纯c语言版本)
操作的命名如下
栈的信息
这是栈的信息,
接下来初始化
我们在创建好栈的信息后定义一个栈,然后进行初始化,初始时我们可以让栈中放4个元素,在开一段可以放入4个元素的内存,让a指向
初始化
初始化要用到的函数malloc,这个不懂的可以看这个
动态内存管理()-CSDN博客
在我们开空间的化可能会开失败,如果开失败的化,直接把返回的指针给ps->a程序会出现内存问题,所以我们创建一个临时变量,存放新开空间首位置的指针,如果这个指针不为空,就把临时的tmp指针给ps->a。这个操作在后续操作用到,比如在入栈时栈满,我们还要进行一次扩容,所以我们可以写一个扩容函数
入栈
代码如下
判空
判空这个操作实现的功能是如果这个栈里面没有元素的化返回假,有元素返回真
在 Stack.h 中加入#include<stdbool.h> 就可以用布尔类型了,我们的栈中的top
真好就是栈中元素的真是个数-1,因为top,从0开始就有元素了,所以返回 top+1;即可
代码如下
出栈
我们判空操作实现后就方便出栈了
在出栈时需要考虑一个栈是否为空的情况所以直接调用上面的函数特判一下,不为空让top--,就可以了
代码
获取栈顶元素
判断一下不是空,然后返回栈中top指向的元素,代码如下
woc,怎末感觉突然没话讲了,
获取栈中元素个数,栈的销毁
完整的代码
//Stack.h
#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<ctype.h>
#include<stdbool.h>
#include<assert.h>
#include<windows.h>
//栈的元素类型
typedef int STaType;
typedef struct Stack
{
STaType* a;
int top;//栈顶
int capacity;//栈满容量
}Stack;
//栈的打印
void Stack_print(Stack p);
//栈中元素的输入
void Stack_scan(STaType* x);
//扩容
void Stack_Check();
//初始化
void Stack_Lnit(Stack* ps);
//入栈,出栈
void Stack_push(Stack* ps, STaType x);
void Stack_pop(Stack* ps);
//获取栈顶元素
STaType Stack_top(Stack* ps);
//获取栈内元素个数
int Stack_size(Stack* ps);
//判空
bool Stack_empty(Stack* ps);
//销毁
void Stack_Destroy(Stack* ps);
//Stack.c
#include"Stack.h"
//typedef struct Stack
//{
// STaType* a;
// int top;//栈顶
// int capacity;//栈满容量
//}Stack;
//栈的打印
void Stack_print(Stack p)
{
printf("\n现在栈如下\n");
while (p.top != -1)
{
printf("%d\n", p.a[p.top]);
p.top--;
}
printf("\n");
printf("\n");
}
//栈中元素的输入
void Stack_scan(STaType* x)
{
scanf("%d", x);
}
//扩容
void Stack_Check(Stack*ps)
{
assert(ps);
int x = ps->capacity==0?4:ps->capacity*2;
if (ps->top == ps->capacity)
{
STaType* tmp = (STaType*)malloc(sizeof(STaType)*x);
assert(tmp);
ps->a = tmp;
}
ps->capacity = x;
}
//初始化
void Stack_Lnit(Stack* ps)
{
assert(ps);
ps->capacity = 4;
ps->top = -1;//栈顶有元素
STaType *tmp= (STaType*)malloc(sizeof(STaType)*ps->capacity);
if (tmp != NULL)
ps->a = tmp;
}
//入栈,出栈
void Stack_push(Stack* ps, STaType x)
{
assert(ps);
Stack_Check(ps);//判断扩容
ps->a[++ps->top] = x;
}
void Stack_pop(Stack* ps)
{
assert(ps);
if(!Stack_empty(ps))
ps->top--;
else
{
printf("栈为空,出栈失败\n");
return;
}
}
//获取栈顶元素
STaType Stack_top(Stack* ps)
{
assert(ps);
if (Stack_empty(ps))
{
printf("栈为空,出栈失败\n");
return 0;
}
return ps->a[ps->top];
}
//获取栈内元素个数
int Stack_size(Stack* ps)
{
assert(ps);
return ps->top + 1;
}
//判空
bool Stack_empty(Stack* ps)
{//为空返回真,不为空返回假
assert(ps);
return ps->top == -1;
}
//销毁
void Stack_Destroy(Stack* ps)
{
if (ps->a)
{
free(ps->a);
}
ps->a = NULL;
ps->top = ps->capacity = 0;
}
//Text.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
void enumm()
{
printf("********************************************************************\n");
printf("********************************************************************\n");
printf("********************************************************************\n");
printf("********************************************************************\n");
printf("**1 初始化 2.入栈 **************\n");
printf("**3 出栈 4.获取栈顶元素 **************\n");
printf("**5 获取栈中元素个数 6判空 **************\n");
printf("**7 销毁栈 0退出 **************\n");
printf("********************************************************************\n");
printf("*******************************************************************\n");
printf("********************************************************************\n");
}
void text()
{
Stack pp;
enumm();
do
{
int po; scanf("%d", &po);
switch (po)
{
case 1://创
Stack_Lnit(&pp);
break;
case 2://入栈
STaType x;
Stack_scan(&x);
Stack_push(&pp, x);
Stack_print(pp);
break;
case 3://出栈
Stack_pop(&pp);
Stack_print(pp);
break;
case 4://获取栈顶元素
STaType xx= Stack_top(&pp);
printf("%d", xx);
break;
case 5://获取栈中元素个数
int n = Stack_size(&pp);
printf("%d", n);
break;
case 6://判空
if (!Stack_empty(&pp)) printf("不是空\n");
else printf("是空\n");
break;
case 7://销毁栈
Stack_Destroy(&pp);
case 0://退出
goto xxx;
break;
}
//system("cls");
} while (1);
xxx:;
}
signed main()
{
text();
getchar();
return 0;
}