栈的基础
来源:互联网 发布:夜的第七章 知乎 编辑:程序博客网 时间:2024/06/05 18:06
1. 栈的基础
栈,也成为堆栈,是一种重要的线性结构。栈具有线性表的特点:每一个元素只有一个前驱元素和后继元素(除了第一个元素和最后一个元素外),但是在操作上与线性表不同,栈是一种操作受限的线性表,只允许在栈的一端进行插入和删除操作。栈可以用顺序存储结构和链式存储结构存储,采用顺序存储结构的栈称为顺序栈,采用链式存储结构的栈称为链式栈。栈的应用十分广泛,在表达式求值、括号匹配时常用到栈的思想。
2. 栈的操作
允许插入和删除操作的一端称为栈顶,另一端称为栈底。栈顶是动态变化的,它由一个称为栈顶指针(top)的变量指示,当表中没有元素时,称为空栈。栈的插入操作称为入栈或进栈,删除操作称为出栈或退栈。
图 堆栈示意图
例如:一个进栈的序列由A、B、C组成,它的出栈序列有ABC、ACB、BAC、BCA和CBA五种可能,只有CAB是不可能的输出序列。因为ABC进栈后,C出栈接着就是B要出栈,不可能A在B之前出栈,所以CAB是不可能的序列。
栈的基本操作包括以下七种:
(1)InitStack(&S):初始化操作,建立一个空栈S。
(2)StackEmpty(S):若栈S为空,返回1,否则返回0。
(3)GetTop(S,&e):返回栈S的栈顶元给e。
(4)PushStack(&S,e):在栈S中插入元素e,使其成为新的栈顶元素。
(5)PopStack(&S,&e):删除栈S的栈顶元素。
(6)StackLength(S):返回栈S的元素个数。
(7)ClearStack(S):清空栈S。
3. 共享栈
栈的应用十分广泛,经常会出现一个程序需要同时使用多个栈的情况。使用顺序栈会由于栈空间的大小难以准确估计,从而造成有的栈溢出,有的栈空间还有空闲,为了解决这个问题,可以让多个栈共享一个足够大的连续存储空间,通过利用栈的动态特性使多个栈存储空间能够互相补充,存储空间得到有效利用,这就是栈的共享。
在栈的共享问题中,最常用的是两个栈的共享,实现方法是两个栈共享一个一维数组空间S(StackSize),两个栈的栈底设置在数组的两端,当有元素进栈时,栈顶位置从栈的两端迎面增长,当两个栈的栈顶相遇时,栈满。共享栈的存储表示如下图所示:
图 两栈共享空间
如上图,设两个栈共享一个一维数组空间Stack[M],将两个栈的栈底分别在该数组空间两端,即Stack[O]和Stack[M-1]。这样,当元素进栈时,两个栈都是从两端向中间伸展。通过两个栈顶指针(top1和top2)的动态变化,使其存储空间相互补充。
两栈共享空间的数据结构定义如下:
- #define M 100 //两栈共享的存储空间大小
- typedef struct
- {
- ElemType Stack[M]; //两栈共享的一维数组空间
- int top[2]; //两栈的栈顶指针
- } DSegStack;
4. 栈的链式表示与实现
在顺序栈中,由于顺序存储结构需要事先静态分配,而存储规模往往又难以确定,如果栈空间分配过小,可能会照成溢出,如果栈空间分配过大,又造成存储空间浪费。因此,为了克服顺序存储的缺点,采用链式存储结构表示栈。
采用链式存储方式的栈称为链栈或链式栈。链栈由一个个节点构成,节点包含数据域和指针域两部分。在链栈中,利用每一个节点的数据域存储栈中的每一个元素,利用指针域表示元素之间的关系。
图 链栈示意图
链栈的数据结构定义如下:
- typedef struct node
- {
- DataType data;
- struct node *next;
- }LStackNode, *LinkStack; //LinkStack为栈顶指针,始终指向链栈的头结点
5. 栈与递归
递归是指在函数的定义中,在定义自己的同时又出现了对自身的调用。如果一个函数在函数体中直接调用自己,则称为直接递归函数。如果经过一系列的中间调用,间接调用自己的函数称为间接递归调用。递归问题可以分解成规模小且性质相同的问题加以解决。
用递归编制的算法具有结构清晰、易读,容易实现并且递归算法的正确性很容易得到证明。但是,递归算法的执行效率比较低,因为递归需要反复入栈,时间和空间开销大。递归算法也完全可以转换为非递归实现,这就是递归的消除。消除递归的方法有两种,一是对于简单的递归可以直接用迭代,通过循环结构就可以消除;另一种方法是利用栈的方式实现。
利用栈模拟递归过程可以通过以下步骤实现:
(1)设置一个工作栈,用于保存递归工作记录,包括实在参数,返回地址等。
(2)将调用函数传递过来的参数和返回地址入栈。
(3)利用循环模拟递归分解过程,逐层将递归过程的参数和返回地址入栈。当满足递归结束条件时,依次逐层退栈,并将结果返回给上一层,直到栈空为止。
- 栈的基础实现
- 栈的基础
- 栈的基础
- 网络基础的基础
- java基础的基础
- Sidekiq基础的基础
- 基础的基础
- 汇编基础的基础
- 栈和队列的基础!!!!
- 栈的实现(栈的基础操作)
- 汇编基础-栈基础
- iptables基础,绝对的基础
- XHTML之基础的基础
- XHTML之基础的基础
- 会计之基础的基础
- 基础篇--堆和栈的区别
- 【基础】关于栈内存分布的测试
- STL栈与队列的基础用法
- 用户名怎么修改
- C语言排序(6)___送数字——(二分查找)
- 用DNS+GeoIP+Nginx+Varnish做世界级的CDN
- 利用wmctrl控制窗口
- 戳破可穿戴设备的泡泡:行业忽悠了我们什么?
- 栈的基础
- 博客
- 面试程序员的时候要问这10个问题
- Android application四大组件的作用
- su:故障鉴定
- 排序基础
- ANT build.xml文件详解
- Redis快速入门、熟悉和使用
- LINUX 注销,关机,重启命令