1、深入Java编程,专业教程,理论讲解部分,Ver3.1,第021课 算法及数据结构,概述:,栈的概念栈的实现,重点:,难点:,栈的实现,栈的实现,4 栈,栈只允许访问一个数据项:即最后插入的数据项。移除这个数据项后才能访问倒数第二个插入的数据项,依此类推。这种机制在不少编程环境中都很有用。,栈提供了一种“后入先出”的一种数据结构,栈是一块连续的(物理的或者逻辑的)存储区域.有两个标识标志出栈的两个端点 栈底和栈顶.,栈需要提供2个最基本的操作压入(push)和弹出(pop),第021课 算法及数据结构,下面我们用一个数组来实现一个最简单的栈.,private int stack;,但是,只有一
2、个数组还无法实现栈得功能,我们还需要一些标识.,private final int SIZE; private final int BOTTOM = 0; private int top;,其中,SIZE是数组得大小,栈得大小要比数组得小1个,随后我们会解释原因.当这个栈被创建后其大小不会改变,所以我们定义它为final(不会改变得变量).BOTTOM标识着这个栈得栈底,它始终为数组得第一个元素,所以为final得0.top标识着这个栈得栈顶,它会随着栈得使用变化.,4.1 栈的初始化,第021课 算法及数据结构,4 栈,初始化栈,BOTTOM,top,0,SIZE,当这个栈被初始化之后,如图
3、,SIZE = size; stack = new intSIZE; top = BOTTOM;,初始化代码如下:,其中,size为初始化参数.可以当作已知量.,第021课 算法及数据结构,4.1 栈的初始化,4 栈,栈被初始化时有一下几点:,2.栈底通常定义于存储空间得一段,而且通常是固定得.,1.存储空间得初始化.如果是动态的仅仅需要得到其大小及初始空间得创建.,3.令栈顶指向栈底.这里我们只需令top = BOTTOM;,此时,一个空栈被创建.,第021课 算法及数据结构,4.1 栈的初始化,4 栈,4.2 空栈的判断,一个栈被建立,我们需要在任意时刻需要了解到它得情况,比如是否为空.,
4、下面我们来看看如何判断一个栈是否为空.,public boolean isEmpty()if(top != BOTTOM)return false;elsereturn true; ,判断得依据是依靠判断top与BOTTOM的关系.,当top =BOTTOM时,此时栈为空,否则栈非空.,第021课 算法及数据结构,4 栈,空栈,BOTTOM,top,0,SIZE,1,2,BOTTOM,top,SIZE,0,非空栈,第021课 算法及数据结构,4.2 空栈的判断,4 栈,4.3 满栈的判断,同样,我们还需要在任何时刻需要判断栈是否为满栈.,public boolean isFull()if(to
5、p != SIZE)return false;elsereturn true; ,判断得依据是依靠判断top与SIZE的关系.,当top =SIZE时,此时栈为满,否则栈不满.,第021课 算法及数据结构,4 栈,空栈,1,2,3,4,5,6,7,BOTTOM,0,SIZE,1,2,BOTTOM,top,SIZE,0,非空栈,top,注意:这里需要声明一点,top指向的是下一个将要使用的空间.,为了数组的安全,不至越界.通常top = SIZE定义为满栈.这就是为什么栈的空间比数组的小的原因.,第021课 算法及数据结构,4.3 满栈的判断,4 栈,4.4 入栈(压栈 push),栈是要用来存
6、储数据的,数据被存储到栈中,这个动作叫入栈或者压栈.,下面我们来看看压栈的实现.,public synchronized void push(int data) throws IllegalStateExceptionif(!isFull()stacktop+ = data;elsethrow new IllegalStateException(“Stack is overload.“); ,第021课 算法及数据结构,4 栈,这里我们要注意入栈的步骤:,1.需要判断栈是否是满栈,如果栈满,那么返回一个异常说明栈已经满了.无法在使其它元素入栈.如果栈非满,那么继续.,2.将数据存储到top指向
7、的空间.由于top始终指向第一个未使用的空间.所以可以将数据存储进去.,3.将top向栈底反向移动一个单位.,注意,第2步与第3步千万不能颠倒.否则会引起栈的存储异常.,第021课 算法及数据结构,4.4 入栈(压栈 push),4 栈,1,2,3,BOTTOM,top,SIZE,0,第3步,1,2,3,BOTTOM,top,SIZE,0,第2步,第1步,判断,1,2,BOTTOM,top,SIZE,0,将3写入top指向位置,top+,第021课 算法及数据结构,4.4 入栈(压栈 push),4 栈,4.5 出栈(弹出 pop),当需要从栈中取出数据时,只能从栈顶取出,这个动作叫出栈.,我
8、们来看看pop如何实现.,public synchronized int pop() throws IllegalStateExceptionif(!isEmpty()return stack-top;elsethrow new IllegalStateException(“Stack is empty.“); ,第021课 算法及数据结构,4 栈,这里我们要注意出栈的步骤:,1.需要判断栈是否是空栈,如果栈空,那么返回一个异常说明栈已经空了.无法弹出.如果栈非空,那么继续.,3.将top指向的数据返回.栈空间中的数据实际上是没有被删除的,但是对于栈来说,该数据已经没有任何意义.当下一次使用该
9、空间时,它会被当作空,由新的数据覆盖掉.,2.将top向栈底方向移动一个单位.,注意,第2步与第3步千万不能颠倒.否则会引起栈的存储异常.,第021课 算法及数据结构,4.5 出栈(弹出 pop),4 栈,1,2,3,4,5,BOTTOM,top,SIZE,0,第3步,1,2,3,4,5,BOTTOM,top,SIZE,0,第2步,第1步,判断,1,2,3,4,5,BOTTOM,top,SIZE,0,top-,将top指向内容返回,第021课 算法及数据结构,4.5 出栈(弹出 pop),4 栈,4.6 栈操作的安全,细心的同学会注意到,在push() pop()方法中都使用了synchron
10、ized 关键字.这是为了使入栈与出栈操作原子化,就是说在入栈与出栈的操作过程中是不允许其它操作干扰的.有了同步的保障,栈的工作才不会出现异常.,下面给出程序的完整代码,及必要注释.,第021课 算法及数据结构,4 栈,public class MyStack private int stack;private final int SIZE;private final int BOTTOM = 0;private int top;public MyStack(int size) super();SIZE = size;stack = new intSIZE;top = BOTTOM;,栈所需要
11、的空间及标志,构造函数,当该类被实例化后,一个栈就创建了.,第021课 算法及数据结构,4 栈,public synchronized void push(int data) throws IllegalStateExceptionif(!isFull()stacktop+ = data;elsethrow new IllegalStateException(“Stack is overload.“); public synchronized int pop() throws IllegalStateExceptionif(!isEmpty()return stack-top;elsethro
12、w new IllegalStateException(“Stack is empty.“); ,第021课 算法及数据结构,4 栈,public boolean isEmpty()if(top != BOTTOM)return false;elsereturn true;public boolean isFull()if(top != SIZE)return false;elsereturn true;,第021课 算法及数据结构,4 栈,public static void main(String args) MyStack ms = new MyStack(20);ms.push(1);
13、ms.push(2);ms.push(3);System.out.println(“1th pop:“+ms.pop();ms.push(4);for(int i = 0;ims.stack.length;i+)System.out.println(ms.stacki); ,main()函数,这里定义了一个名为ms的栈,然后将1,2,3分别入栈,之后作了一个出栈操作,最后又将4入栈. 程序的末尾检查了一下栈的存储情况.,第021课 算法及数据结构,4 栈,小结:,栈的定义满栈的条件空栈的条件入栈的操作顺序出栈的操作顺序,第021课 算法及数据结构,1、栈是一种( )的存储结构A) 先进先出 B
14、)后进后出 C)先进后出 D)任意进出 2、判断栈空的条件是( )A)top = BOTTOM B)top = SIZEC)BOTTOM = SIZE D)SIZE = 0 3、判断栈满的条件是( )A)top = BOTTOM B)top = SIZEC)BOTTOM = SIZE D)SIZE = 0 4、入栈的顺序( )A)top+ B)判断栈空 C)判断栈满 D)数据写入top指向的位置 5、出栈的顺序( )A)top- B)判断栈空 C)判断栈满 D)读出top指向的位置,小测验(单选题答案):,第021课 算法及数据结构,1、栈是一种(C)的存储结构A) 先进先出 B)后进后出 C
15、)先进后出 D)任意进出 2、判断栈空的条件是(A)A)top = BOTTOM B)top = SIZEC)BOTTOM = SIZE D)SIZE = 0 3、判断栈满的条件是(B)A)top = BOTTOM B)top = SIZEC)BOTTOM = SIZE D)SIZE = 0 4、入栈的顺序(CDA)A)top+ B)判断栈空 C)判断栈满 D)数据写入top指向的位置 5、出栈的顺序(BAD)A)top- B)判断栈空 C)判断栈满 D)读出top指向的位置,小测验(单选题答案):,第021课 算法及数据结构,试着使用链表来实现一个栈.使其具有栈的最基本的操作提示:栈顶定义在链表尾部操作会比较方便.,课后作业:,第021课 算法及数据结构,