栈的主要特点就是先进后出,根据此可以使用线性表或者链表来实现。这里选择动态线性表来实现
1:定义
typedef struct Stack
{
int* a;
int top;
int capacity;
}ST;
定义了基地址a,top来指向栈顶,capacity来表示空间大小。
2:初始化
void StackInit(ST* ps)
{
ps->a = (int*)malloc(4 * sizeof(int));
ps->top = 0;
ps->capacity = 4;
}
首先对a分配了4个内存空间,将top置为0,capacity为4(开辟4个空间)。这里top的值是有2中情况。第一种置为0,那么将先把值赋给top的位置,然后top++,这种情况下top是在新元素的下一个位置(此时top 位置是没有元素的,也就是top位置是栈顶元素的下一个位置)。第二种是top赋值-1,这种情况首先将top++,然后再将值赋给top的位置,这种条件下,top指向的永远是最新放入的元素(也就是top位置是栈顶元素)。
3:入栈
void StackPush(ST* ps,int x)
{
if (ps->capacity == ps->top)
{
int* tmp = (int*)realloc(ps->a, ps->capacity * 2 * sizeof(int));
ps->a = tmp;
ps->capacity *= 2;
}
ps->a[ps->top] = x;
ps->top++;
}
入栈本质上就是直接在栈顶放入元素,首先进行一次内存的判断(动态线性表同款判断代码~无需详细解释)将top 的位置放入新元素,最后再top++即可。
4:出栈
void StackPop(ST* ps)
{
ps->top--;
}
出栈比较简单,有人可能会将栈顶元素置为0来代表该元素出栈,但是这对于int型数据是可以的,但若是栈中每一个元素都是自己定义的结构体又该如何呢?总的来说还是不太合适,所以直接将top--即可,代表出栈(毕竟处理元素都是根据top来说的)
5:判断是否为空
bool StackEmpty(ST* ps)
{
return ps->top == 0;
}
此处用到bool类型(布尔类型:只有true和false两种,分别代表1和0)
这里直接返回ps->top==0即可,如果成立,那么返回true(也就是返回1),代表空。如果不成立,那么返回false(也就是返回0)
6:取栈顶元素
int StackTop(ST* ps)
{
return ps->a[ps->top-1];
}
这里直接返回数组的top-1位置的值即可。千万不要把这个函数写成先ps->top--;再返回a[top],因为在ps->top--的操作已经对这个栈发生了改变,top的位置已经不是预设的那样指向最新元素的下一处位置了,如果要再出栈的话,这个top此时已经指向了一个确定的元素,不满足我们的预设了,情况不可控。于是这里直接返回top-1位置的值。
7:销毁栈
void StackDestory(ST* ps)
{
free(ps->a);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
首先因为在初始化时malloc了内存赋予了基地址a,既然要销毁这段开辟的内存,那么与malloc对应的就是free,于是就有了第一句代码,释放掉了数组a。释放后可以将a的地址改为NULL来保证a不会成为野指针(指向了乱七八糟的位置),然后capacity和top全置为0来彻底销毁这个栈。
test测试函数
这里需要注意栈的打印不像是链表等结构可以用写一个print函数来打印,这里的输出就要通过写的StackEmpty函数来判断,当栈不空时,就打印栈顶的元素,
void test()
{
ST st;
StackInit(&st);
StackPush(&st, 1);
StackPush(&st, 2);
StackPush(&st, 3);
StackPush(&st, 4);
StackPush(&st, 5);
while (!StackEmpty(&st))
{
printf("%d", StackTop(&st));
StackPop(&st);
}
StackDestory(&st);
}
下面是全代码
#include<iostream>
using namespace std;
typedef struct Stack
{
int* a;
int top;
int capacity;
}ST;
void StackInit(ST* ps)
{
ps->a = (int*)malloc(4 * sizeof(int));
ps->top = 0;
ps->capacity = 4;
}
void StackPush(ST* ps,int x)
{
if (ps->capacity == ps->top)
{
int* tmp = (int*)realloc(ps->a, ps->capacity * 2 * sizeof(int));
ps->a = tmp;
ps->capacity *= 2;
}
ps->a[ps->top] = x;
ps->top++;
}
bool StackEmpty(ST* ps)
{
return ps->top == 0;
}
int StackTop(ST* ps)
{
return ps->a[ps->top-1];
}
void StackPop(ST* ps)
{
ps->top--;
}
void StackDestory(ST* ps)
{
free(ps->a);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
void test()
{
ST st;
StackInit(&st);
StackPush(&st, 1);
StackPush(&st, 2);
StackPush(&st, 3);
StackPush(&st, 4);
StackPush(&st, 5);
while (!StackEmpty(&st))
{
printf("%d ", StackTop(&st));
StackPop(&st);
}
StackDestory(&st);
}
int main()
{
test();
return 0;
}
以下是输出结果