一、栈的顺序存储的一个很大的缺陷就是必须事先确定数组存储空间大小,万一不够用了,就要用编程手段来扩展数组的容量,非常麻烦。
二、对于一个栈,也只能尽量考虑周全,设计出合适大小的数组来处理;但是对于两个相同类型的栈,可以做到最大限度地利用其事先开辟的存储空间来进行操作。
三、如果有两个相同类型的栈,为它们各自开辟了数组空间,极有可能是第一个栈已经满了,再进栈就溢出了,而另外一个栈还有很多存储空间。所以两栈共享空间的思想是:让一个栈的栈底为数组的开始端,即下标为0处,另一个栈的栈底为数组的末端,即下标为数组长度的n-1出,这样,两个栈如果增加元素,就是两端点向中间延伸。当两个栈见面之时,也就是两个指针相差1时,即top1 + 1 == top2时为栈满。
四、两栈共享空间的C语言代码实现:
#include "stdio.h" #include "stdlib.h" #include "io.h" #include "math.h" #include "time.h" #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define MAXSIZE 20 /* 存储空间初始分配量 */ typedef int Status; typedef int SElemType; /* SElemType类型根据实际情况而定,这里假设为int */ /* 两栈共享空间结构 */ typedef struct { SElemType data[MAXSIZE]; int top1; /* 栈1栈顶指针 */ int top2; /* 栈2栈顶指针 */ }SqDoubleStack; Status visit(SElemType c) { printf("%d ",c); return OK; } /* 构造一个空栈S */ Status InitStack(SqDoubleStack *S) { S->top1=-1; S->top2=MAXSIZE; return OK; } /* 把S置为空栈 */ Status ClearStack(SqDoubleStack *S) { S->top1=-1; S->top2=MAXSIZE; return OK; } /* 若栈S为空栈,则返回TRUE,否则返回FALSE */ Status StackEmpty(SqDoubleStack S) { if (S.top1==-1 && S.top2==MAXSIZE) return TRUE; else return FALSE; } /* 返回S的元素个数,即栈的长度 */ int StackLength(SqDoubleStack S) { return (S.top1+1)+(MAXSIZE-S.top2); } /* 插入元素e为新的栈顶元素 */ Status Push(SqDoubleStack *S,SElemType e,int stackNumber) { if (S->top1+1==S->top2) /* 栈已满,不能再push新元素了 */ return ERROR; if (stackNumber==1) /* 栈1有元素进栈 */ S->data[++S->top1]=e; /* 若是栈1则先top1+1后给数组元素赋值。 */ else if (stackNumber==2) /* 栈2有元素进栈 */ S->data[--S->top2]=e; /* 若是栈2则先top2-1后给数组元素赋值。 */ return OK; } /* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */ Status Pop(SqDoubleStack *S,SElemType *e,int stackNumber) { if (stackNumber==1) { if (S->top1==-1) return ERROR; /* 说明栈1已经是空栈,溢出 */ *e=S->data[S->top1--]; /* 将栈1的栈顶元素出栈 */ } else if (stackNumber==2) { if (S->top2==MAXSIZE) return ERROR; /* 说明栈2已经是空栈,溢出 */ *e=S->data[S->top2++]; /* 将栈2的栈顶元素出栈 */ } return OK; } Status StackTraverse(SqDoubleStack S) { int i; i=0; while(i<=S.top1) { visit(S.data[i++]); } i=S.top2; while(i<MAXSIZE) { visit(S.data[i++]); } printf("\n"); return OK; } int main() { int j; SqDoubleStack s; int e; if(InitStack(&s)==OK) { for(j=1;j<=5;j++) Push(&s,j,1); for(j=MAXSIZE;j>=MAXSIZE-2;j--) Push(&s,j,2); } printf("栈中元素依次为:"); StackTraverse(s); printf("当前栈中元素有:%d \n",StackLength(s)); Pop(&s,&e,2); printf("弹出的栈顶元素 e=%d\n",e); printf("栈空否:%d(1:空 0:否)\n",StackEmpty(s)); for(j=6;j<=MAXSIZE-2;j++) Push(&s,j,1); printf("栈中元素依次为:"); StackTraverse(s); printf("栈满否:%d(1:否 0:满)\n",Push(&s,100,1)); ClearStack(&s); printf("清空栈后,栈空否:%d(1:空 0:否)\n",StackEmpty(s)); return 0; } 输出为: 栈中元素依次为:1 2 3 4 5 18 19 20 当前栈中元素有:8 弹出的栈顶元素 e=18 栈空否:0(1:空 0:否) 栈中元素依次为:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 栈满否:0(1:否 0:满) 清空栈后,栈空否:1(1:空 0:否)
五、两栈共享空间的Java语言代码实现:
- 接口类:
package bigjun.iplab.doubleStack; public interface DoubleStackINF { // 判断顺序栈是否为空 public boolean isStackEmpty(); // 将一个已经存在的顺序栈置成空表 public void stackClear(); // 求顺序栈的长度 public int stackLength(); // 读取顺序栈1的栈顶元素 public int getTop1Elem() throws Exception; // 读取顺序栈2的栈顶元素 public int getTop2Elem() throws Exception; // 在顺序栈中插入元素e public void stackPush(int stackNumber, int e) throws Exception; // 删除顺序栈中的栈顶元素 public void stackPop(int stackNumber) throws Exception ; // 输出顺序栈中的所有元素 public void stackTraverse(); }
- 实现类:
package bigjun.iplab.doubleStack; public class DoubleStack implements DoubleStackINF{ private final static int MAXSIZE = 20; private int[] stackElem; private int top1; // 将top1设置为指向栈1栈顶元素的存储位置即数组下标 private int top2; // 将top2设置为指向栈2栈顶元素的存储位置即数组下标 public DoubleStack() { top1 = -1; top2 = MAXSIZE; stackElem = new int[MAXSIZE]; } public boolean isStackEmpty() { if (top1 == -1 && top2 == MAXSIZE) return true; else return false; } public void stackClear() { top1 = -1; top2 = MAXSIZE; } public int stackLength() { return (top1 + 1) + (MAXSIZE - top2); } public int getTop1Elem() throws Exception{ if (top1 == -1) throw new Exception("栈1为空,无法获取栈顶元素"); return stackElem[top1]; } public int getTop2Elem() throws Exception{ if (top2 == MAXSIZE) throw new Exception("栈2为空,无法获取栈顶元素"); return stackElem[top2]; } public void stackPush(int stackNumber, int e) throws Exception { if (top1 + 1 == top2) throw new Exception("栈为满,无法在栈顶插入元素e"); if (stackNumber == 1) { top1++; stackElem[top1] = e; }else if (stackNumber == 2) { top2--; stackElem[top2] = e; } } public void stackPop(int stackNumber) throws Exception { if (stackNumber == 1) { if (top1 == -1) throw new Exception("栈1为空,无法获取栈顶元素"); top1--; }else if (stackNumber == 2) { if (top2 == MAXSIZE) throw new Exception("栈2为空,无法获取栈顶元素"); top2++; } } public void stackTraverse() { System.out.print("此时,栈中的元素为: "); int i = 0; while (i <= top1) { System.out.print(stackElem[i++] + " "); } i = top2; while (i < MAXSIZE) { System.out.print(stackElem[i++] + " "); } System.out.println(); } public static void main(String[] args) throws Exception { DoubleStack seqStack = new DoubleStack(); for (int j = 1; j <= 5; j++) seqStack.stackPush(1,j); for (int i = MAXSIZE; i >= MAXSIZE -2 ; i--) { seqStack.stackPush(2, i); } seqStack.stackTraverse(); System.out.println("栈的长度为: " + seqStack.stackLength()); seqStack.stackPop(2); seqStack.stackTraverse(); System.out.println("栈1的栈顶元素为: " + seqStack.getTop1Elem()); System.out.println("栈2的栈顶元素为: " + seqStack.getTop2Elem()); System.out.println("栈的长度为: " + seqStack.stackLength()); for (int i = 6; i <= MAXSIZE-2; i++) { seqStack.stackPush(1,i); } seqStack.stackTraverse(); System.out.println("栈1的栈顶元素为: " + seqStack.getTop1Elem()); System.out.println("栈2的栈顶元素为: " + seqStack.getTop2Elem()); System.out.println("栈顶元素为: " + seqStack.getTop2Elem()); System.out.println("栈的长度为: " + seqStack.stackLength()); System.out.println("栈是否为空: " + seqStack.isStackEmpty()); seqStack.stackClear(); System.out.println("栈是否为空: " + seqStack.isStackEmpty()); } }
- 输出:
此时,栈中的元素为: 1 2 3 4 5 18 19 20 栈的长度为: 8 此时,栈中的元素为: 1 2 3 4 5 19 20 栈1的栈顶元素为: 5 栈2的栈顶元素为: 19 栈的长度为: 7 此时,栈中的元素为: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 栈1的栈顶元素为: 18 栈2的栈顶元素为: 19 栈顶元素为: 19 栈的长度为: 20 栈是否为空: false 栈是否为空: true