【数据结构学习记录5】——栈(顺序栈)

一.概念

栈是一种仅在表尾进行插入或者删除操作的线性表。且表的首尾两端都有特殊的含义:表头我们一般称为栈底,表尾(最后一个元素的位置)称为栈顶,不含元素或者栈底=栈顶的栈,我们称之为空栈
所以,栈是一种先进后出的表结构。这种情况,和我们的火车调度站非常相似。

二.栈的结构定义

因为栈的内部储存结构,可以用顺序结构,也可以用链式结构,但在这部分储存方式与前面的线性表、单链表相似,所以本文采用顺序存储的方法来实现。

1.栈定义

对于一个栈,我们要定义三个部分,一个是base作为我们基础的“容器”存放我们的数据,然后还得要有一个top栈顶指针,来指向我们当前的栈顶元素,因为是顺序表,所以我们还得有一个maxlen来储存base的最大长度,以免越界。top可以是一个整形,通过base+top的方式,得到栈顶指针,当然,也可以直接将top声明成和base相同的类,然后存放栈顶的指针。因为本来就是顺序表,所以越简单越好,所以采用整形的方式去存储。
在这里插入图片描述

2.初始化栈

对于栈的初始化,我们只用申请一个默认长度的空间,赋值给base,然后将maxlen更新至我们初始化的长度,最后top=0,也就是指向了base

3.销毁栈

直接free掉我们的base

4.栈是否为空

我们直接判断top==0

5.栈长度

因为是顺序存储结构,所以并不需要去遍历整个表,直接返回top,栈顶指针,就是我们的栈的长度了。

6.栈顶元素

如果栈不为空,那么返回*(base+top)的值就行

7.入栈

我们只需要更新栈顶的指针位置,并赋上我们要压入的值,这样元素就入栈了。
当然,我们得判断base的存储空间够不够,如果不够还需要realloc base,以免造成越界。按照我的习惯,我喜欢入了栈后再检查并扩容,做好主准备。

8.出栈

返回当前栈顶指针指向的地址的值,然后将栈顶指针-1

三.代码实现

因为只要知道原理了,那么实现起来就比较简单,所以就不怎么添加注释了。

#include <stdio.h>
#include <stdlib.h>

#define OK      1
#define ERROR    0
#define DEFAULT_LEN     20
#define EXTEND_LEN      5

typedef struct elemType{
    int data;
}elemType;

typedef struct Stack{
    elemType *base;
    int top;
    int maxlen;
}Stack;

Stack* StackInit(void);
int GetTop(Stack *S, elemType *elem);
int Push(Stack* S, elemType elem);
elemType Pop(Stack* S);
int IsEmpty(Stack *S);

int main()
{
    Stack* s = StackInit();
    elemType test;
    test.data = 123;
    Push(s,test);
    test.data = 456;
    Push(s,test);
    test.data = 789;
    Push(s,test);
    while(IsEmpty(s) == 0)
    {
        printf("%d\n", Pop(s).data);
    }

    return 0;
}

Stack* StackInit(void)
{
    Stack *S = (Stack*)malloc(sizeof(Stack));
    if (S == NULL)
    {
        return ERROR;
    }
    S->base = (elemType *)malloc(sizeof(elemType)*DEFAULT_LEN);
    S->top = 0;
    S->maxlen = DEFAULT_LEN;
    if (S->base != NULL)
    {
        return S;
    }   
    else
    {
        exit(1);
    }
}

int GetTop(Stack *S, elemType *elem)
{
    if (S->base != NULL && S->top != 0)
    {
        elem = S->base + S->top;
        return OK;
    }
    else
    {
        return ERROR;
    }
}

int Push(Stack *S, elemType elem)
{
    if (S->top < S->maxlen)
    {
        S->top += 1;
        *(S->base+S->top) = elem;
        if (S->top >= S->maxlen)
        {
            S->base = (elemType*)realloc(S->base, sizeof(elemType)*(S->maxlen + EXTEND_LEN)); 
            if (S->base != NULL)
            {
                return OK;
            }
            else
            {
                exit(1);
            }
            
        }
    }
    else
    {
        return ERROR;
    }
}

elemType Pop(Stack* S)
{
    elemType *elem;
    if (S->top > 0)
    {
        elem = S->base+S->top;
        S->top -= 1;
        return *elem;
    }
    else
    {
        exit(2);
    }
}

int IsEmpty(Stack *S)
{
    if (S->top > 0)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

康娜喵

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

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

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

打赏作者

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

抵扣说明:

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

余额充值