• 栈与队列的简单实现(stack and queue)


    一 - 栈的概念

            栈,又名堆栈,属于运算受限制的线性表,讲究先进先出。

            举个例子,我们经常乘坐的电梯,先进去的人往往会被挤到最里面,而最后进来的人刚好到了门口。那么出电梯的时候最后进来的人肯定是先出去的。

            再举个例子,手枪的弹夹,先按入弹夹的子弹肯定是最后一个打出去的,而最后按入弹夹的子弹肯定是第一个打出去的。

    ☟手枪弹夹的填弹与射击图☟

     这两个例子描述的都是栈,现在对栈的性质有所了解了吧。

            栈的性质:栈是一种先进先出的线性表。

            栈的分类:

                    Ⅰ 顺序存储结构:单栈和共享栈

                    Ⅱ 链式存储结构

            共享栈:即两个顺序栈共享存储空间。

            栈的顺序结构与链式结构的区别:顺序结构适合数据元素不大的情况,而链式结构适合数据元素变化比较大的情况。这是为什么呢?是因为顺序结构需要事先估计存储大小,而链式结构无需事先估计存储大小。

    二 - 栈的相关操作

    ☟栈的操作☟

    定义

    queue <数据类型> a;//定义一个名叫a的栈。

    压入

    a.push(item);//在栈a的栈顶压入新成员

    弹出

    a.pop()//将a的栈顶元素弹出

    判断是否为空

    a.empty();//判断a是否为空,如果是,则返回true,否则返回false。

     返回栈顶值

    a.top();//返回栈a的栈顶值

    返回栈的元素个数

    a.size();//返回栈a的元素个数

    ☟样例操作代码☟

    1. #include
    2. #include
    3. using namespace std;
    4. int main()
    5. {
    6. stack <int> a;//定义一个int型的栈a
    7. a.push(1);//将1压入栈a
    8. a.pop();//将a的栈顶弹出
    9. int tmp=a.top();//将a的栈顶的值返回给tmp
    10. bool flag=a.empty();//如果a是空的,flag就时true,否则flag就是false。
    11. int len=a.size();//将栈a里的元素个数反馈给len
    12. return 0;
    13. }

    三 - 顺序存储栈

            顺序存储栈,也是用数组完成的。

            先开辟一片内存,每push一个新元素,top值就加1。

    下面我们开始吧!

    定义

    1. #define STACK_SIZE 10
    2. typedef struct stack
    3. {
    4. ElemType data[STACK_SIZE];//data 栈数据空间
    5. int top;//栈顶指针
    6. }stack;*pstack

    初始化

    1. void init(pstack pst)
    2. {
    3. if(pst!=NULL)
    4. {
    5. pst->top = 0;
    6. }
    7. }

    压栈

            首先,需要先判断栈是否满了。

    1. int full(pstack pst)
    2. {
    3. rerurn pst->top == STACK_SIZE ?1:0;
    4. }

            然后再压栈

    1. int push(pstack pst ,ElemType val)
    2. {
    3. if(full(pst))
    4. {
    5. return 0;
    6. }
    7. pst->data[pst->top] = val;
    8. pst->top++;
    9. return 1;
    10. }

    出栈

            首先要判断栈是否为空。

    1. int empty(pstack pst)
    2. {
    3. return pst->top == 0 ? 1: 0;
    4. }

            然后,在出栈

    1. int pop(pstack pst)//只删除元素,不获取元素
    2. {
    3. if(empty(pst))
    4. {
    5. return 0;
    6. }
    7. pst->top--;//data[top - 1]是无法将元素删除的。我们只需要将top--,就可以删除元素。
    8. return 1;
    9. }

    获取栈顶元素

    1. //返回值返回状态 形参把栈顶元素带出
    2. int gettop(pstack pst,ElemType* prt)//拿到栈顶元素,不删除元素
    3. {
    4. if(empty(pst))//栈空
    5. {
    6. return 0;
    7. }
    8. *prt = pst->data[pst->top-1];
    9. return 1;
    10. }

    四 - 链式存储栈

    我们都知道栈有栈顶指针,链表有头指针,这两者是缺一不可的,所以在进行链栈的设计的时候,我们就把栈顶放在单链表的头部。从而方便我们的插入和删除的操作。那么链栈的基本结构如下所示:

     现在我们写一下代码吧。

    定义

    1. typedef int ElemType;
    2. typedef struct Node
    3. {
    4. ElemType data;
    5. struct Node* next;
    6. }Node,stack,*pstack;

     初始化

    1. void init(pstack pst)
    2. {
    3. if(pst!=NULL)
    4. {
    5. pst->next = NULL;
    6. }
    7. }

    压栈

    由于是链式结构,所以我们不需要判断栈是否满了。插入新节点需要插入一个新节点,所以我们写一个购买节点的函数。

    1. Node* buyNode(ElemType val)
    2. {
    3. Node* pnewnode = (Node*)malloc(sizeof(Node));
    4. pnewnode->data = val;
    5. pnewnode->next = NULL;
    6. }

    图1是本来的栈,现在来了一个新节点,我们把新节点和a[n]连接起来,再修改栈顶即可(如图2所示)。

              

    图1-原来的栈的样子                                  图2-插入新节点的操作。 

    现在我们可以添加元素了

    1. void push(pstack pst,ElemType val)//元素做一个链表的头插
    2. {
    3. Node* pnewnode = buyNode(val);
    4. pnewnode->next = pst->next;
    5. pst->next = pnewnode;
    6. }

    出栈

    我们要先判断栈是否为空

    1. int empty(pstack pst)
    2. {
    3. return pst->next == NULL ? 1 : 0;
    4. }

    把上面的图1和图2反过来就是pop的过程。

    1. int pop(pstack pst)
    2. {
    3. if(empty(pst))
    4. {
    5. return 0;
    6. }
    7. Node* pcur = pst->next;//第一个数据结点
    8. pst->next = pcur->next;
    9. free(pcur);
    10. return 1;
    11. }

    获取栈顶元素

    1. int gettop(patsck pst,ElemType* prt)
    2. {
    3. if(empty(pst))
    4. {
    5. return 0;
    6. }
    7. *prt = pst->next->data;//第一个数据结点的数据
    8. return 1
    9. }

    摧毁函数

    由于是链式结构,所以我们要摧毁栈。

    1. void destory(pstack pst)
    2. {
    3. Node* pcur = pst->next;
    4. Node* pnext = NULL;
    5. while(pcur !=NULL)
    6. {
    7. pnext = pcur->next;
    8. free(pcur);
    9. pcur = pnext;
    10. }
    11. pst->next = NULL;
    12. }

    好啦,这就是栈的全部内容啦,有没有觉得对栈更了解了呢?感谢大家的阅读。

  • 相关阅读:
    基于stm32单片机农业智能温室大棚温湿度光照测量报警系统Proteus仿真
    华为认证 | 考HCIE,真的不需要先考HCIP
    每日一题 78子集(模板)
    golang中快速用melody搭建轻量的websocket服务
    WSDM‘22推荐系统论文梳理
    HarmonyOS模拟器(phone-x86-api9)一直卡顿的解决方法
    【2023最新版】MySQL安装教程
    游戏ip多开安全指南:保障多重账号操作安全性
    【012】wireshark抓包分析libpq和postmaster之间的通信
    [极客大挑战 2020]Roamphp2-Myblog - 伪协议+文件上传+(LFI&ZIP)||(LFI&Phar)【***】
  • 原文地址:https://blog.csdn.net/weixin_46522531/article/details/126432780