栈的基本操作

文章介绍了如何使用动态线性表来实现栈的主要操作,包括栈的初始化、入栈、出栈、判断栈是否为空、获取栈顶元素以及销毁栈。在入栈时进行了内存判断和扩展,出栈时直接修改top指针。测试函数展示了如何使用这些操作打印并清空栈。
摘要由CSDN通过智能技术生成

栈的主要特点就是先进后出,根据此可以使用线性表或者链表来实现。这里选择动态线性表来实现

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;
}

以下是输出结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值