基础数据结构:栈

说到栈,相信大家肯定多少都有听说过吧!C语言里的函数在进行调用时便是借助系统中的“栈”结构,其次生活中也有许多栈的应用实例,最容易想象的就是弹夹了,弹夹的结构就是“栈”的应用之一。说完实例,相信大家也能看出“栈”的特性了吧~那就是“后进先出(Last in First out)”。

  • 栈其实本质上也是属于线性表,只不过是较为特殊的线性表,与其特性相匹配的还有队列,队列也是特殊的线性表之一,我们在下一篇会为大家介绍。
  • 栈呢大体即分为:栈顶、栈底,无论是入数据还是出数据,都需要通过栈顶,因此这也保证了它的特性“后进先出”:先进去的会被压在栈底,而后进去的则是在栈顶。
  • 对栈进行数据的插入操作即被称作入栈(压栈),删除数据的操作被称作出栈。

关于模拟实现栈
实现栈可以使用数组/链表都行(按需灵活使用):

1. 数组实现栈:

数组的首位做栈底,尾部做栈顶,入数据即等同于尾插数据,出数据即等于尾删数据 数组比较合适,唯一缺陷就是要增容

2.链表实现栈:

链表的话,单链表如果是尾作栈顶,尾删效率比较低,所以建议使用双向带头循环链表 如果要用单链表,则使用头作栈顶即可

由于数组实现较为便捷,故本篇模拟实现的是用数组实现的栈,如果大家感兴趣也可自行去尝试用链表去实现栈,其实难度也算相当。


接下来即看如何自己模拟实现一个栈结构吧

首先还是先来看看整体的栈结构是怎么样的

typedef int STDataType;

typedef struct Stack
{
    STDataType *stack;
    int size;
    int top;
    int capacity;
}Stack;

整体结构即包括了一个可动态增长的数组模拟的栈帧空间、栈内的数据个数、栈顶位置以及栈容量等,这即是最基本的一个栈结构。

 首先还是需要对栈进行一个简单的初始化操作:init_stack()

void StackInit(Stack *ST)
{
    STDataType *tmp = (STDataType*)malloc(sizeof(STDataType)*4);
    assert(tmp);
    ST->stack = tmp;
    ST->size = 0;
    ST->capacity = 4;
    ST->top = -1;
}

我们可以看到初始化时,我们将栈顶初始化为-1,这是因为插入数据时,数组首元素下标为“0”,当然也可以初始化为“0”,那么注意进行操作时需要对应做出一点变化。

初始化完栈之后就是对栈的操作了:添加数据、删除数据等

添加数据:push()

void push(Stack *ST,STDataType x)
{
    assert(ST);
    if(ST->size == ST->capacity)
    {
        STDataType *tmp = (STDataType*)realloc(ST->stack,sizeof(STDataType)*ST->capacity*2);
        assert(tmp);
        ST->stack = tmp;
        ST->capacity *= 2;
    }
    ST->stack[ST->size] = x;
    ST->size++;
    ST->top++;
}

入数据即是直接往数组中添加数据即可。

删除数据:pop()

void pop(Stack *ST)
{
    assert(ST);
    assert(ST->top >= 0);
    ST->size--;
    ST->top--;
}

删除数据时由于是用数组结构作为栈结构,所以直接将数据容量减一即可(相当于尾删)

剩下的一些就是简单的接口用于栈的辅助使用:返回栈顶数据、返回栈空间容量、判断栈是否为空以及销毁栈空间

返回栈顶数据:top()

STDataType top(Stack *ST)
{
    assert(ST);
    assert(ST->top >= 0);
    return ST->stack[ST->top];
}

直接返回栈顶指针对应的数据即可

返回栈空间容量:size()

int size(Stack *ST)
{
    assert(ST);
    return ST->size;
}

栈结构设计时即包含了栈的容量,其随着栈的数据个数相应变换,所以直接返回即可

判断栈是否为空:empty()

bool empty(Stack *ST)
{
    assert(ST);
    return ST->top == -1;
}

由于我们最开始的栈顶指针指向“-1”的位置,所以如果栈顶指针指向的位置是初始位置,该栈即为空

销毁栈空间:destroy() 

void StackDestroy(Stack *ST)
{
    assert(ST);
    free(ST->stack);
    ST->size = 0;
    ST->capacity = 0;
    ST->top = -1;
    ST->stack = NULL;
}

销毁时,将动态开辟的空间释放以及其它数据量进行初始化即可


整体通过数组结构对栈的模拟实现, 可以看到并没有什么复杂的地方,都是对数组进行特定化操作,让数组满足栈的使用特点即可。

如果本篇文章对你有帮助的话,可以顺带点个赞即收藏哩~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

c.Coder

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值