【数据结构--栈】

栈的基本概念

栈是一种基于先进后出(FILO)或者后进先出(LIFO)的数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。

我们称数据进入到栈的动作为压栈(入栈),数据从栈中出去的动作为弹栈(出栈)

image.png

链式栈

链式栈就是使用链表的方式实现的栈,为了实现先进后出(FILO),我们可以采用链表中的“头插法”实现一个链式栈。

但是与之前所学的链表不同的是:链式栈中不需要头结点(数据域为空的结点)。

image.png

如上图所示,指向链表中的第一个结点的指针就是栈顶指针,指向链表最后一个结点的指针就是栈底指针。

1、链式栈的描述

typedef struct StackNode{
    ElemType data; //数据域
    struct StackNode * next; //指针域
}StackNode, *LinkStack;

2、链式栈的初始化

/*
 * @brief 初始化一个链式栈
 * @return 返回链式栈的栈顶指针
 * */
LinkStack stack_init()
{
    LinkStack s;
    //因为没有头结点,因此初始化链式栈时因为栈为空,所以栈顶指针赋值为NULL
    s = NULL; 
    return s;
}

3、入栈

入栈:链表的头插法,在链表的第一个结点之前插入新的结点

image.png

/*
 * @brief 入栈
 * @param s 栈顶指针的地址
 * @param data 需要入栈的元素
 * @return 成功返回TRUE,失败返回FALSE
 * */
int push(LinkStack *s, ElemType data)
{
    if (NULL == s)
        return FALSE;
​
    StackNode *p = (StackNode *)malloc(sizeof(StackNode));
    p->data = data;
​
    //新的结点的next指向链表的第一个结点(原来的栈顶)
    p->next = *s;
    //栈顶指针指向新的结点(p变成了链表上的第一个结点)
    *s = p;
  
    return TRUE;
}
​
void print_stack(LinkStack s)
{
    if (NULL == s)
        return ;
​
    StackNode *t = s;
    while (t)
    {
        printf("%d ", t->data);
        t = t->next;
    }
    printf("\n");
}

4、出栈

/*
 * @brief 出栈
 * @param s 栈顶指针的地址
 * @param data 需要出栈的元素
 * @return 成功返回TRUE,失败返回FALSE
 * */
int pop(LinkStack *s, ElemType *data)
{
    if (NULL == s || NULL == data || NULL == *s)
        return FALSE;
  
    *data = (*s)->data;
    StackNode *t = (*s)->next;
    free(*s);
    *s = t;
    return TRUE;
}

5、获取栈顶元素

/*
 * @brief 获取栈顶元素 
 * @param s 栈顶指针
 * @param data 需要入栈的元素
 * @return 成功返回TRUE,失败返回FALSE
 * */
int get_top(LinkStack s, ElemType *data)
{
    if (NULL == s || NULL == data)
        return FALSE;
    *data = s->data;
​
    return TRUE;
}

6、销毁链式栈

/*
 * @brief  销毁链式栈
 * @param s 栈顶指针的地址
 * @return 成功返回TRUE,失败返回FALSE
 * */
int stack_destroy(LinkStack *s)
{
    if (NULL == s || NULL == *s)
        return FALSE;  
​
    StackNode *t = *s;;
    while (t)
    {
        t = (*s)->next; 
        free(*s);
        *s = t;
    }
    //*s = NULL;
    return TRUE;
}
  • 18
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值