顺序栈
1.定义
栈是仅限定在表尾进行插入和删除操作的线性表。允许进行插入和删除的一端称为栈顶(也叫表尾),另一端为栈底。栈又称为后进先出的线性表。由于栈本身是一个线性表,所以线性表的顺序存储结构和链式存储结构对于栈来说,同样是适用的。
2.栈的顺序存储结构
栈的顺序存储结构又称为顺序栈,线性表是用数组来实现的,而栈也是线性表,所以我们使用数组来实现栈。
2.1 栈的顺序存储结构实现
由于栈顶进行数据的插入和删除操作,而栈底变化不大,所以使用数组下标为0的一端作为栈底比较好。我们定义一个top变量指向栈顶元素在数组中的位置,还必须指明栈的长度StackSize,top变量需小于栈的长度。
代码实现:
class LineStack{ //空栈的判定条件为top=-1 int top=-1; static int maxSize=8; static Object[] array=new Object[maxSize]; public LineStack(){ } }
2.2 进栈操作
算法思路:
1. 首先判断top指针与栈长度的大小,top指针的最大值为栈长减1;
2. 进栈操作时首先将top指针增加1;
3. 给top指针指向的数组元素的位置赋值;
代码实现:
public static void pushStackTest(LineStack stack,Object e){ //top指向的是元素在数组中的位置,空栈时值为-1 if(stack.top==stack.maxSize-1){ System.out.println("栈满"); }else{ //入栈:1.先将栈指针加1 stack.top=stack.top+1; //2.给指针指向的数组位置赋值 stack.array[stack.top]=e; } }
2.3 出栈操作
算法思路:
1. 判断是否为空栈;
2. 若栈非空,指针下移;
代码实现:
public static void popStackTest(LineStack stack){ Object e=null; //判断是否为空栈 if(stack.top==-1){ System.out.println("空栈"); }else{ //弹栈元素 e=stack.array[stack.top]; System.out.println(e); //指针下移 stack.top=stack.top-1; } }
顺序栈进栈和出栈操作的时间复杂度分析:因为二者都没有for循环,所以时间复杂度为O[1]。
2.4 两栈共享空间
对于两个相同类型的栈,我们会为它开辟两个数组空间,但有可能是一个栈已经满了,另一个栈还有很大的存储空间,此时完全可以使用一个数组来存储两个栈。栈1的栈底作为数组的始端,即数组下标为0处,栈2的栈底为数组的末端,即数组下标为n-1处。这样进栈相当于两个指针向中间靠拢的过程,出栈相当于两个指针远离的过程。当top1=-1并且top2=n时,表示栈空;当top1+1=top2时,表示栈满。
两栈共享空间结构的代码实现:
class DoubleStack{ static int maxSize=14; //两栈存储在一个数组空间中 static Object[] array=new Object[maxSize]; int top1=-1; int top2=maxSize; public DoubleStack(){ } }
2.4.1 顺序栈进栈操作
算法思路:
1. 判断是否栈满,当top1+1=top2时,表示栈满;
2. 判断哪个栈有元素进栈,如果栈1进栈,top1加1后给数组赋值;若栈2进栈,top2减1后给数组赋值。
代码实现:
public static void pushDoubleStackTest(DoubleStack doubleStack,Object e,int stackNumber){ //首先判断是否栈满 if(doubleStack.top1+1==doubleStack.top2){ System.out.println("栈满"); }else if(stackNumber==1){ //栈1有元素进栈 doubleStack.top1=doubleStack.top1+1; doubleStack.array[doubleStack.top1]=e; }else if(stackNumber==2){ //栈2有元素进栈 doubleStack.top2=doubleStack.top2-1; doubleStack.array[doubleStack.top2]=e; } }
2.4.2 顺序栈出栈操作
算法思路:
1. 首先判断哪个栈出栈;
2. 若为栈1出栈,top1减1;若为栈2出栈,top2加1;
代码实现:
public static void popDoubleStackTest(DoubleStack doubleStack,int stackNumber){ if(stackNumber==1){ if(doubleStack.top1==-1){ System.out.println("栈1为空栈"); }else{ System.out.println("出栈元素为:"+doubleStack.array[doubleStack.top1]); doubleStack.top1=doubleStack.top1-1; } }else if(stackNumber==2){ if(doubleStack.top2==doubleStack.maxSize){ System.out.println("栈2为空栈"); }else{ System.out.println("出栈元素为:"+doubleStack.array[doubleStack.top2]); doubleStack.top2=doubleStack.top2+1; } } }
完整代码:
package com.java.Stack; /* * 栈的顺序存储结构及实现 * */ public class LineStackTest { static LineStack stack=new LineStack(); static DoubleStack stack2=new DoubleStack(); public static void main(String[] args){ pushStackTest(stack, 0); pushStackTest(stack, 1); pushStackTest(stack, 2); pushStackTest(stack, 3); for(int j=0;j<stack.maxSize;j++){ System.out.println("stack:"+stack.array[j]); } popStackTest(stack); popStackTest(stack); pushDoubleStackTest(stack2,"S",1); pushDoubleStackTest(stack2,"D",2); pushDoubleStackTest(stack2,"A",2); pushDoubleStackTest(stack2,"T",2); pushDoubleStackTest(stack2,"F",1); for(int j=0;j<stack2.maxSize;j++){ System.out.println("stack2:"+stack2.array[j]); } popDoubleStackTest(stack2,1); popDoubleStackTest(stack2,1); popDoubleStackTest(stack2,2); for(int j=0;j<stack2.maxSize;j++){ System.out.println("stack2出栈:"+stack2.array[j]); } } //两栈共享空间的出栈操作 public static void popDoubleStackTest(DoubleStack doubleStack,int stackNumber){ if(stackNumber==1){ if(doubleStack.top1==-1){ System.out.println("栈1为空栈"); }else{ System.out.println("出栈元素为:"+doubleStack.array[doubleStack.top1]); doubleStack.top1=doubleStack.top1-1; } }else if(stackNumber==2){ if(doubleStack.top2==doubleStack.maxSize){ System.out.println("栈2为空栈"); }else{ System.out.println("出栈元素为:"+doubleStack.array[doubleStack.top2]); doubleStack.top2=doubleStack.top2+1; } } } //两栈共享空间的进栈操作 public static void pushDoubleStackTest(DoubleStack doubleStack,Object e,int stackNumber){ //首先判断是否栈满 if(doubleStack.top1+1==doubleStack.top2){ System.out.println("栈满"); }else if(stackNumber==1){ //栈1有元素进栈 doubleStack.top1=doubleStack.top1+1; doubleStack.array[doubleStack.top1]=e; }else if(stackNumber==2){ //栈2有元素进栈 doubleStack.top2=doubleStack.top2-1; doubleStack.array[doubleStack.top2]=e; } } //出栈操作 public static void popStackTest(LineStack stack){ Object e=null; //判断是否为空栈 if(stack.top==-1){ System.out.println("空栈"); }else{ //弹栈元素 e=stack.array[stack.top]; System.out.println(e); //指针下移 stack.top=stack.top-1; } } //进栈操作 public static void pushStackTest(LineStack stack,Object e){ //top指向的是元素在数组中的位置,空栈时值为-1 if(stack.top==stack.maxSize-1){ System.out.println("栈满"); }else{ //入栈:1.先将栈指针加1 stack.top=stack.top+1; //2.给指针指向的数组位置赋值 stack.array[stack.top]=e; } } } class LineStack{ //空栈的判定条件为top=-1 int top=-1; static int maxSize=8; static Object[] array=new Object[maxSize]; public LineStack(){ } } class DoubleStack{ static int maxSize=14; //两栈存储在一个数组空间中 static Object[] array=new Object[maxSize]; int top1=-1; int top2=maxSize; public DoubleStack(){ }