数据结构——栈(Stack)

这篇具有很好参考价值的文章主要介绍了数据结构——栈(Stack)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.栈的介绍

2.栈工程

2.1 栈的定义

2.1.1 单链表实现栈

2.1.2 数组实现栈

2.1.2.1 静态数组栈

2.1.2.2 动态数组栈

2.2 栈的函数接口

2.2.1 栈的初始化

2.2.2 栈的数据插入(入栈)

2.2.3 栈的数据删除(出栈)

2.2.4 判断栈是否为空

2.2.5 取栈顶数据

2.2.6 栈数据统计

2.2.7 栈销毁

3. 栈总结反思


1.栈的介绍

        栈这个东西我们并不陌生,有过一些基础知识的同志都知道,在存储器映像中就有一块存储区域被称为栈。这个栈主要是存储非静态局部变量,函数调用所开辟出的栈帧也在这块区域。对于这块区域,我们很明确的一点就是它的特征:先进后出,后进先出。在程序运行时(以Linux+IA32为例),栈顶指针esp在面对push和pop指令时会对应的减或加,栈空间的开辟和释放都是由esp指针来标定的。所以可以看到在栈区内,当要完成空间释放或申请时,总是在对最顶部的空间进行操作,即满足“先进后出,后进先出”的规则。

        我们今天要介绍的栈则是一种数据结构,也属于线性表的一种,其重要特征就是我们刚才所提到的先进后出,后进先出。当数据存入时,会采取push(入栈/压栈)操作,将数据存储在栈顶;当数据删除时,会采取pop(出栈/弹栈)操作,将位于栈顶位置的数据删除。

数据结构——栈(Stack),数据结构

2.栈工程

2.1 栈的定义

        在实现栈的时候,我们需要考虑数据存储的方式。我们到目前掌握的存储方式有如顺序表的数组的结构,除此之外,还有链表结构。在实现栈这一方面,链表和数组的方式存储都可以。但是考虑到我们在需要频繁地访问栈顶,我们需要对这两种方式有所规定。

2.1.1 单链表实现栈

        使用单链表的时候我们要规定好栈顶和栈底。因为对于栈这种数据结构,我们需要频繁地访问栈顶,但是对于单链表而言其数据的插入是将结点链接在链表末端。两相对比,我们发现使用单链表在入栈出栈的时候代价很大,需要遍历链表。所以我们一般不使用单链表来实现栈。

2.1.2 数组实现栈

        使用数组实现栈也同样需要先明确栈顶栈底的位置。因为栈顶是“灵活多变”的,栈顶会随着数据的插入和删除而更改位置。对于一个数组而言很明显下标大的一端更容易适应这样的特性,所以我们一般将下标为0的一端作为栈底,将下标较大的一端作为栈顶。

        在明确了数组的格式后,我们自然的想到动态的数组和静态的数组两种结构。

2.1.2.1 静态数组栈

        对于一个静态数组栈,其数组长度是定长的,我们定义一个常量来统一管理。其栈结构(结构体)中除了一个存储数据的定长数组之外,还应该有一个成员来标识栈顶的位置,便于我们对栈进行访问。

//静态
typedef int STDataType;
#define N 10
typedef struct Stack
{
 STDataType _a[N];
 int _top; // 栈顶
}Stack;
2.1.2.2 动态数组栈

        对于动态数组的栈来说,为满足其灵活管理空间的功能,其结构体内需要一个指针指向我们动态开辟的数组。同样的我们也需要一个成员标识栈顶位置,还需要一个成员存储数组容量上限。

typedef int STDataType;

typedef struct Stack
{
	STDataType* data;
	int top;
	int capacity;
}ST;

2.2 栈的函数接口

2.2.1 栈的初始化

        当新建一个栈后,我们需要对其结构体进行初始化。将指针值为空,将容量初始化为0,同时将表示栈顶的成员置为-1。top初始化为-1,表示栈顶所在元素下标,-1即为栈为空。也可以将top初始化为0,表示栈内元素个数。此处选择第一种方式。

void STInit(ST* pst)
{
	assert(pst);

	pst->data = NULL;
	pst->top = -1;
	pst->capacity = 0;
}

2.2.2 栈的数据插入(入栈)

        当要在栈中插入数据时,我们首先要判断是否需要扩容,从而防止越界访问的问题。修改完容量后只需要将数据存储到数组的末端(栈顶)即可。

void STPush(ST* pst,STDataType x)
{
	assert(pst);

	if (pst->top + 1 == pst->capacity)
	{
		int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
		STDataType* tmp = realloc(pst->data, newcapacity*sizeof(STDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}
		pst->data = tmp;
		pst->capacity = newcapacity;
	}
	pst->top++;
	pst->data[pst->top] = x;
}

2.2.3 栈的数据删除(出栈)

        出栈只需要将top减1即可,注意使用断言限制空指针与越界访问。

void STPop(ST* pst)
{
	assert(pst);
	assert(pst->top != -1);

	pst->top--;
}

2.2.4 判断栈是否为空

        栈是否为空只需要判断top成员是否为-1即可。

bool STEmpty(ST* pst)
{
	assert(pst);

	return pst->top == -1;
}

2.2.5 取栈顶数据

        因为top保存的是栈顶的下标,所以取栈顶元素只需要访问该下标元素即可。

STDataType STTop(ST* pst)
{
	assert(pst);
	assert(pst->top != -1);

	return pst->data[pst->top];
}

2.2.6 栈数据统计

        该接口是为了输出此时栈内的数据个数,只需将栈顶下标加一即可。

int STSize(ST* pst)
{
	assert(pst);

	return pst->top + 1;
}

2.2.7 栈销毁

        销毁栈需要将其数组空间释放,并将结构体内成员值全部初始化。

void STDestroy(ST* pst)
{
	assert(pst);

	free(pst->data);
	pst->data = NULL;
	pst->capacity = 0;
	pst->top = -1;
}

3. 栈总结反思

        栈主要实现了“先进后出,后进先出”的特殊功能,这就意味着栈这种数据结构在面对一些满足该特性的一些特殊情况下才能很好的适配。其结构和实现并不复杂,相较于其他数据结构很容易理解,特征也非常明显,处理好一些类似于下标之类的小细节就没问题了。文章来源地址https://www.toymoban.com/news/detail-812559.html

到了这里,关于数据结构——栈(Stack)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】栈(Stack)的实现 -- 详解

    1、概念 栈 :一种特殊的线性表,其只允许在表尾进行插入和删除元素操作。 进行数据插入和删除操作的一端称为栈顶,另一端称为栈底 。栈中的数据元素遵守后进先出 LIFO(Last In First Out)的原则。 压栈 :栈的插入操作叫做进栈 / 压栈 / 入栈, 入数据在栈顶 。 出栈 :栈

    2024年02月14日
    浏览(44)
  • 【数据结构】 栈(Stack)与栈的模拟实现

    🎈栈:一种特殊的线性表,其 只允许在固定的一端进行插入和删除元素操作 。进行数据插入和删除操作的一端称为 栈顶 ,另一端称为 栈底 。 栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则 压栈 :栈的插入操作叫做进栈/压栈/入栈, 入数据在栈顶 。 出栈 :栈的

    2024年02月11日
    浏览(49)
  • 在JavaScript中的栈数据结构(Stack )

    JavaScript 中可以通过数组实现栈数据结构。栈是一种遵循后进先出(LIFO)原则的数据结构,它只允许在栈顶进行插入和删除操作。 栈是一种遵从后进先出(LIFO)原则的有序集合。新添加的或待删除的元素都保存在栈的 同一端,称作栈顶,另一端就叫栈底。在栈里,新元素都

    2024年02月10日
    浏览(38)
  • 【数据结构】栈和队列超详解!(Stack && Queue)

    栈 :一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则 压栈 : 栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。 出栈 : 栈的删除操

    2024年02月04日
    浏览(43)
  • Java 【数据结构】 栈(Stack)和队列(Queue)【神装】

      登神长阶  第三神装 S tack    第四神装 Queue    目录 🔋一.栈 Stack 💻1.概念 🖥️2.基本操作  🖨️3.相关OJ题   🖱️4.栈、虚拟机栈和栈帧的区别 🪫二.队列 Queue 🖲️1.概念 💽2.基本操作 🔌三.总结与反思         在 Java 中,栈(Stack)是一种后进先出(LIFO)的数

    2024年04月27日
    浏览(35)
  • 数据结构入门到入土——栈(Stack)和队列(Queue)

    目录 一,栈(Stack) 1.1 概念 1.2 栈的使用 1.3 栈的模拟实现 1.4 栈的应用场景 1.5 栈,虚拟机栈,栈帧有什么区别? 二,队列(Queue) 2.1 概念 2.2 队列的使用  2.3 队列模拟实现 2.4 循环队列 三,双端队列 栈 :一种特殊的线性表,其 只允许在固定的一端进行插入和删除元素操

    2024年02月02日
    浏览(54)
  • 【LeetCode】设计数据结构 | List、Stack、Queue、DLinkedList

    设计链表(中等) 707. 设计链表 冗余版 代码复用简化版 用栈实现队列(简单) 232. 用栈实现队列 用队列实现栈(简单) 225. 用队列实现栈 方法一:双队列实现 方法二:单队列实现 设计循环队列(中等) 622. 设计循环队列 使用数组实现 使用链表实现 设计循环双端队列(中

    2024年02月14日
    浏览(34)
  • 【数据结构 C语言版】第四篇 栈、堆栈、Stack(超级详细版)

    写在前面 更新情况记录: 最近更新时间 更新次数 2022/10/18 1 参考博客与书籍以及链接: (非常感谢这些博主们的文章,将我的一些疑问得到解决。) 参考博客链接或书籍名称 《数据结构》陈越 代码随想录 总目录:目前数据结构文章太少,没有写。 正文 如果你c语言还有困

    2023年04月09日
    浏览(33)
  • 【数据结构与算法】6、栈(Stack)的实现、LeetCode:有效的括号

    🌱 栈 是一种特殊的线性表, 只能在一端进行操作 🌱 往栈中 添加 元素的操作,一般叫做 push ( 入栈 ) 🌱 从栈中 移除 元素的操作,一般叫做 pop ,出栈(只能移除栈顶元素),也叫做: 弹出栈顶元素 🌱 后进先出 的原则, L ast I n F irst O ut, LIFO 注意:这里的 栈 与内

    2024年02月13日
    浏览(39)
  • 【数据结构】【栈(stack)应用】四则运算表达式求值(带括号)

            先理解原理,再看代码,注意标红字体很重要!结尾附完整测试代码,C语言实现! 更新留言:         本来是侧重演示栈结构的使用,后面评论区发现很多朋友对这个四则运算比较感兴趣,特此做了更新,新增了对负数的运算支持。         若您也有新的想法

    2024年02月08日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包