一、棧的順序存儲的一個很大的缺陷就是必須事先確定數組存儲空間大小,萬一不夠用了,就要用編程手段來擴展數組的容量,非常麻煩。
二、對於一個棧,也只能盡量考慮周全,設計出合適大小的數組來處理;但是對於兩個相同類型的棧,可以做到最大限度地利用其事先開辟的存儲空間來進行操作。
三、如果有兩個相同類型的棧,為它們各自開辟了數組空間,極有可能是第一個棧已經滿了,再進棧就溢出了,而另外一個棧還有很多存儲空間。所以兩棧共享空間的思想是:讓一個棧的棧底為數組的開始端,即下標為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