对于栈的理解,早就在上C++课的时候,程老师就给我们做过简单的介绍和使用,今年接触了数据结构这本书,有了一个全面的学习,不得不说是一本很难啃的一本书,但是为了写出更好的程序代码,这门课是在所难免的。
在数据结构中,栈是一类重要的抽象数据类型。从数据结构角度看,栈也是一种线性结构,属于线性表,其特殊性在于栈的基本操作是线性表操作的子集,它是操作受限的线性表。从数据类型角度看,它和线性表是大不相同的抽象的多型数据类型。
栈的定义
栈(stack)是限定仅在表尾进行插入或删除操作的线性表。因此,对栈来说,表尾端有其特殊含义,称为栈顶(top),相应地,表头端称为栈底(bottom)。不含元素的空表称为空栈。假设栈S=(a1,a2,a3,...,an),则称a1为栈底元素,an为栈顶元素。栈中元素按a1,a2,...,an的次序进栈,退栈的第一个元素应为栈顶元素。换句话说,栈的修改是按后进先出的原则进行的。因此,栈又称为后进先出的线性表。下面的图很好的解释了这个原则。
栈的表示和实现
和线性表类似,栈也有两种存储表示方法。
顺序栈
先来说一下顺序栈:即栈的顺序存储结构是利用一组地址连续的存储单元依次存放在自栈底到栈顶的数据元素,同时附设指针top表示栈顶元素在顺序栈中的位置。top为栈顶指针,其初始值指向栈底,每当插入新的栈顶元素时,指针top增1.删除栈顶元素时,指针top减1,因此,非空栈中的栈顶指针始终在栈顶元素的下一个位置上。下面的图很好的说明了顺序栈中数据元素和栈顶指针之间的对应关系。
链栈
顺序栈在运算过程中可能发生“溢出”现象(上溢和下溢),即存在栈满以后就不能再进栈的问题,这时候就用到了栈的链式存储结构,也就是所谓的链栈。其各结点的结构与单链表中的结点结构完全相同。结点包括两个域:其中的存储数据元素的信息的域称为数据域,存储直接后继存储位置的域称为指针域。指针域中存储的信息叫做指针或链。在这里学过链表的知识就会知道链栈是怎样实现基本操作的,下面的图很好的解释了这个问题。
一顺序栈的定义
通常的习惯做法是以top=0表示空栈。由于栈在使用过程中所需最大空间的大小难以估计,在初始化设空栈时不应限定栈的最大容量。一个较合理的做法就是:先为栈分配一个基本容量,然后再应用的过程中,当栈的空间不够使用时再逐段扩大。为此,可以设定两个常量:STACK_INIT_SIZE(存储空间初始分配量)和STACKINCREMENT(存储空间分配增量)。
<span style="font-size:18px;">#define STACK_INIT_SIZE 100//存储空间初始分配量 #define STACKINCREMENT 10//存储空间分配增量 typedef int SElemType;//重新定义SElemType为int型 typedef struct{//重新定义SqStck为结构类型 SElemType *base;//栈底指针 SElemType *top;//栈顶指针 int stacksize;//栈的当前可使用的最大容量 }SqStack</span>
二链栈的定义
链栈最重要的就是结点类型的定义和实现
<span style="font-size:18px;">typedef int ElemType;//重新定义ElemType为int型 typedef struct node//重新定义node为结构类型 { ElemType date;//定义的结点的数据域 struct node *next;//定义的结点的指针域 }node,*pointer;//定义的指向node结构类型指针变量pointer </span>