• 数据结构第四课 -----线性表之栈


    作者前言

    🎂 ✨✨✨✨✨✨🍧🍧🍧🍧🍧🍧🍧🎂
    ​🎂 作者介绍: 🎂🎂
    🎂 🎉🎉🎉🎉🎉🎉🎉 🎂
    🎂作者id:老秦包你会, 🎂
    简单介绍:🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂🎂
    喜欢学习C语言和python等编程语言,是一位爱分享的博主,有兴趣的小可爱可以来互讨 🎂🎂🎂🎂🎂🎂🎂🎂
    🎂个人主页::小小页面🎂
    🎂gitee页面:秦大大🎂
    🎂🎂🎂🎂🎂🎂🎂🎂
    🎂 一个爱分享的小博主 欢迎小可爱们前来借鉴🎂


    栈的概念和结构

    栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除的一端称为栈顶,另一端称为栈底栈里的元素遵循后进先出的原则
    压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶
    出栈:栈的删除操作叫做出栈,出数据也在栈顶
    在这里插入图片描述
    在这里插入图片描述
    栈顶的位置是变化的,不是在某一个地方,栈顶是插入数据和删除数据的位置
    如果我们要实现栈,有两种方法

    1. 数组栈
      在这里插入图片描述

    使用数组来当作栈,栈底和栈顶的位置没有任何规定,但是我们一般是使用尾部为栈顶,头部为栈底,这样就可以减少数据的移动,空间不够就扩容,

    1. 链式栈
      在这里插入图片描述
      栈顶和栈底的位置随意,哪边都可以,而我们使用链表一般都是单链表
      在这里插入图片描述
      还要一个栈的出栈的顺序有多种,不会只有一种
      下面我就以数组栈来写一个栈

    栈的设计

    栈的创建和初始化

    创建

    typedef int TackDataType;
    typedef struct SLtack
    {
    	TackDataType* TData;
    	TackDataType Top;//标识栈顶位置
    	int Capacity;
    }SLtack;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    初始化

    void TackInit(SLtack* pst)
    {
    	assert(pst);
    	pst->TData = NULL;
    	pst->Top = 0;//栈顶元素的下一个
    	pst->Capacity = 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    这里的top的初始化有两种:
    1.top 表示的是栈顶元素,我们要初始化为-1,
    2.top表示栈顶元素的下一个 我们要初始化为0
    原因:
    在这里插入图片描述
    假设我们初始化为0 且top是表示栈顶元素,就像上面这种情况,我们无法判断top为0时,栈是否还有元素,当我们表示top表示栈顶元素的下一个,top为0,栈就没有元素,或者我们top初始化为-1,top为栈顶元素,即使top为0,那栈还是有元素的

    栈的释放

    //释放
    void TackDestroy(SLtack* pst)
    {
    	assert(pst);
    	free(pst->TData);
    	pst->TData = NULL;
    	pst->Top = 0;
    	pst->Capacity = 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    入栈

    void TackcapacityAdd(SLtack* pst)
    {
    	assert(pst);
    	//扩容
    	pst->Capacity = (pst->Capacity == 0 ? 4 : pst->Capacity * 2);
    	TackDataType* tmp = realloc(pst->TData, sizeof(TackDataType) * pst->Capacity);
    	if (tmp == NULL)
    	{
    		perror("realloc");
    		return;
    	}
    	pst->TData = tmp;
    	
    }
    //插入数据
    void TackPushData(SLtack* pst, TackDataType elemest)
    {
    	assert(pst);
    	//判断容量
    	if (pst->Capacity == pst->Top)
    	{
    		TackcapacityAdd(pst);
    		printf("扩容成功\n");
    		
    	}
    	assert(pst->Capacity != pst->Top);
    	pst->TData[pst->Top] = elemest;
    	pst->Top++;
    	
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    出栈

    //删除数据
    void TackPopData(SLtack* pst)
    {
    	assert(pst);
    	if(pst->Top)
    		pst->Top--;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    栈顶

    //找出栈顶
    TackDataType* TackTop(SLtack* pst)
    {
    	assert(pst);
    	return pst->TData + (pst->Top - 1);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    栈是否为空

    //判断栈是否为空
    bool Empty(SLtack* pst)
    {
    	assert(pst);
    	return pst->Top == 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    栈的长度

    //栈的长度
    int TackSize(SLtack* pst)
    {
    	assert(pst);
    	return pst->Top;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    第二种方法

    这种是把top初始化为-1

    typedef char TackDataType;
    typedef struct Stack
    {
        TackDataType * a;
        int top; //栈顶元素
        int capacity;
    }Stack;
    //初始化
    void TackInit(Stack *pst)
    {
        assert(pst);
        pst->a = NULL;
        pst->top = -1;
        pst->capacity = 0;
    }
    // 入栈
    void TackPush(Stack *pst, TackDataType elemest)
    {
        assert(pst);
        //判断是否满了
        if ((pst->top) +1 == pst->capacity)
        {
            pst->capacity = (pst->capacity == 0? 4 : pst->capacity * 2);
            TackDataType* tmp = (TackDataType*)realloc(pst->a,sizeof(Stack) * pst->capacity);
            if (tmp == NULL)
            {
                perror("realloc");
                return;
            }
            pst->a = tmp;
    
        }
        pst->a[++(pst->top)] = elemest;
    
    }
    //出栈
    void TackPop(Stack *pst)
    {
        assert(pst);
        if(pst->top != -1)
            pst->top--;
    }
    //长度
    int TackSize(Stack *pst)
    {
        assert(pst);
        return (pst->top) + 1;
    }
    //是否为空
    bool TackEmpty(Stack *pst)
    {
        assert(pst);
        return pst->top == -1; 
    }
    //栈顶元素
    TackDataType TackTop(Stack *pst)
    {
        assert(pst);
        return pst->a[pst->top];
    }
    //释放
    void TackDestroy(Stack *pst)
    {
        free(pst->a);
        pst->a = NULL;
        pst->top = -1;
        pst ->capacity = 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    总结

    栈的简单设计就到这里了,如果想要设置链式栈可以动手自己设计,后续会更新相关的代码

  • 相关阅读:
    [学习笔记]PageRank算法
    毕设 飞机订票系统
    Mysql配置binlog并实现数据库备份恢复
    码农的转型之路-全力以赴升级物联网浏览器(IoTBrowser)
    linux shell数组与字典用法总结
    PyTorch Geometric (PyG) 包 文档学习笔记(持续更新ing...)
    推荐系统专题 | 推荐系统架构与单域跨域召回模型
    最详尽教程完整介绍-Windows 的 Linux 子系统-WSL1&WSL2
    叮~程序员,你的专属1024程序员节已到账,请注意查收!
    Android系统实现多网共存且能独立上外网
  • 原文地址:https://blog.csdn.net/m0_69984273/article/details/134391189