1.什么是数据结构
数据存储于计算机的内存中,如图形似排成1列的箱子,每1个箱子里存储1个数据。数据存储于内存中时,决定了数据的顺序和位置关系便是数据结构。
2. 数据结构分类
常用的数据结构有:数组,链表,栈,队列,堆,树,图,哈希表等。本篇整理栈。
3. 栈
栈也是一种数据呈线性排列的数据结构,不过在这种结构中,我们只能访问最新添加的数据。栈就像是一摞书,拿到新书时我们会把它放在书堆的最上面,取书时也只能从最上面的新书开始取。
3.1 栈的概念图
3.2 栈的解释
像栈这种最后添加的数据最先被取出,即“ 后进先出” 的结构,我们称为 Last In First Out,简称 LIFO。与链表和数组一样,栈的数据也是线性排列,但在栈中,添加和删除数据的操作只能在一端进行,访问数据也只能访问到栈顶的数据。想要访问中间的数据时,就必须通过出栈操作将目标数据移到栈顶才行。
3.3 栈的时间复杂度
进栈:栈顶指针+1,新插入元素赋值给栈顶空间,不涉及任何循环,时间复杂度为
出栈:将要删除的栈顶元素赋值给e,栈顶指针-1,不涉及任何循环,时间复杂度为
3.4 栈的应用1:四则运算表达式求值
栈只能在一端操作这一点看起来似乎十分不便,但在只需要访问最新数据时,使用它就比较方便了。
比如,规定(AB(C(DE) F)(G((H) I J) K)) 这一串字符中括号的处理方式如下:首先从左边开始读取字符,读到左括号就将其入栈,读到右括号就将栈顶的左括号出栈。此时,出栈的左括号便与当前读取的右括号相匹配。通过这种处理方式,我们就能得知配对括号的具体位置。
3.5 栈的应用2:递归
递归是栈的一个很重要的应用。所谓递归就是函数自己调用自己来解决问题,看一个经典的例子:斐波那契数列
在递归执行过程中,需要一个栈保存递归调用前的参数及递归的返回地址。参数为Fib中的现行值,返回地址为递归语句的下一语句入口地址。
具体实现为:
(1)遇递归调用时,将当前参数与返回地址压入栈中;
(2)遇递归返回语句时,将栈顶的参数及返回地址一并出栈,按当前返回地址继续执行
从递归调用的过程可知,它们刚好符合后进先出的原则。因此,利用栈实现递归过程再合适不过。别忘了设置递归停止的条件,即满足时不再调用自身而是直接返回退出。否则的话就会陷入永不结束的无穷递归中,最后造成内存崩溃。
4. C语言实现栈的基本操作
说明:栈分两种:静态栈和动态栈
(1)静态栈:以数组作为数据的存储。
(2)动态栈:以链表作为数据的存储方式。
本文采用链表的动态栈。
因为用链表实现栈,其实其本质就是一个链表,只不过对该链表的插入(push)和删除(pop)操作都在该链表的一端进行(该段被称为栈顶,且人为限制就只在该栈顶进行操作),所以该链表就会具有了“先进后出”的特性,则被称为栈结构。
#include