您的位置:首页 > 新闻 > 热点要闻 > 六安官网_贵阳网络科技有限公司_关键词优化建议_南京百度竞价推广公司排名

六安官网_贵阳网络科技有限公司_关键词优化建议_南京百度竞价推广公司排名

2025/1/15 7:25:17 来源:https://blog.csdn.net/2301_80392199/article/details/142908284  浏览:    关键词:六安官网_贵阳网络科技有限公司_关键词优化建议_南京百度竞价推广公司排名
六安官网_贵阳网络科技有限公司_关键词优化建议_南京百度竞价推广公司排名

文章目录

  • 前言
  • 一、栈的概念及结构
  • 二、关于实现栈的分析
    • 关于栈顶指针top
    • 关于结构体
    • 栈的初始化
    • 入栈
    • 出栈
    • 获取栈顶元素
    • 获取栈元素个数
    • 判断栈是否为空
    • 栈的销毁
  • 三、实际使用效果
  • 总结


前言

  栈就是一个比较实用的数据结构了,且大致逻辑就是套用之前的两种线性表

  具体选择哪种呢?请看正文!


一、栈的概念及结构

  栈是指一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则(与我们后面要学的队列先进先出的思想刚好相反)

这里主要分享的是跟数据结构相关的栈,而不是指存储内存一块内存区域栈区,栈区是指CPU寄存器里的某个指针所指向的一片内存区域(存放函数的参数值,局部变量的值等)

栈有两种核心操作:压栈和入栈

  • 压栈:栈的插入操作叫做进栈/压栈/入栈。入数据在栈顶
  • 出栈:栈的删除操作叫做出栈。出数据也在栈顶

在这里插入图片描述
在这里插入图片描述

所以我们可以发现,栈的入栈顺序只有一种,但是却可以有很多种出栈方式

题目:一个栈的入栈序列为ABCDE,则不可能的出栈序列为( )
A.ABCDE // 放一个拿一个
B.EDCBA // 全部放完后再连续拿五次
C.DCEBA
D.ECDBA
答案:D

二、关于实现栈的分析

  栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小,实现起来也更容易,且我们在顺序表那里也说过了静态表实用价值不大,于是我们这里采用动态顺序表来实现栈

关于栈顶指针top

请注意,虽然这里说top是栈顶“指针”,其实并不是一个真正的指针,而是一个下标,只是起到指向作用,故采取这一称呼

我们可以注意到,栈顶有两种定义方式:

  1. top为-1代表空,top为0代表一个元素
  2. top为0代表空,top指向下一个元素下标

其实两种都行,只是对于后面的插入数据即入栈时候的操作有所差别:
在这里插入图片描述

在这里我才用第二种方式,令top一开始为0,即让top指向下一个元素的下标

关于结构体

typedef int StackDataType;
typedef struct Stack
{StackDataType* a;int top;int capacity;
}ST;

栈的初始化

除了验空外还是一样的置空指针,且让栈顶指针指向第一个位置,容量也设为0

void STInit(ST* pst)
{assert(pst);//指向一个有效的结构体pst->a = NULL;pst->top = pst->capacity = 0;
}

入栈

同前面一样,既然是往数组里塞东西,就必须要验证是否满栈
不一样的是,我们在这里验证是否满栈并没有单独封装成一个函数,这是因为我们只有在栈顶这一个地方进行入栈操作,其实就是尾插,因此不需要单独再实现一个函数
在这里插入图片描述

void STPush(ST* pst, StackDataType x)
{assert(pst);if (pst->top == pst->capacity){int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;StackDataType* tmp = (StackDataType*)realloc(pst->a, sizeof(StackDataType)*newcapacity);if (tmp == NULL){perror("realloc fail!!!");return ;}pst->capacity = newcapacity;pst->a = tmp;//保证安全返回}pst->a[pst->top] = x;//插入 pst->top++;//注意top的意义--之后里面为1没有给数值
}

出栈

注意栈顶指针是指向栈顶元素的下一个位置的下标,那我们不是将栈顶指针-1不就完成了出栈操作吗

其实就是尾删

void STPop(ST* pst)
{assert(pst);assert(pst->top > 0);//top为0,则是为空pst->top--;//元素个数--
}

获取栈顶元素

注意栈顶指针是栈顶元素的下一个位置的下标,所以我们要减一才能得到正确的数据,但是不能自减!因为这里并没有出栈的操作

StackDataType STTOP(ST* pst)//得到栈顶元素
{assert(pst);return pst->a[pst->top-1];//这里减的话就会有问题
}

获取栈元素个数

乐,其实还是看栈顶指针top,因为是指向下一个元素的下标,下标又是从0开始,两者一结合,那么top其实就是元素个数

int STSize(ST* pst)
{assert(pst);return pst->top;
}

判断栈是否为空

栈为空,就是大小是否为0,结合上一个函数,我们可以很自然而然的写出

bool STEmpty(ST* pst)
{assert(pst);return pst->top == 0;
}

栈的销毁

销毁,首先就是要回收Stack结构体里面的 STDataType* 指针所指向的内存并置空指针

void STDestroy(ST* pst)//销毁
{assert(pst);free(pst->a);pst->a = NULL;pst->top = pst->capacity = 0;
}

三、实际使用效果

// 各接口一览
void STInit(ST* pst);
void STDestroy(ST* pst);void STPush(ST* pst, StackDataType x);
void STPop(ST* pst);StackDataType STTOP(ST* pst);
int STSize(ST* pst);

在这里插入图片描述


总结

  栈是我们学习的第一个实用数据结构,且我们在未来的学习会经常遇到它,请好好体会它“后进先出”的思想,想想可能会有哪些具体实用场景

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com