題目
請利用兩個棧sI和s2來模擬-一個隊列,假設棧中元素爲int型,棧中元素最多爲maxSize。己知棧的3個運算定義如下。
- push(ST,x):元素x入ST棧。
- pop(ST,&x): ST棧頂元素出棧,賦給變量X。
- isEmpty(ST):判斷ST棧是否爲空。
如何利用棧的運算來實現該隊列的3個運算: enQueue (元素入隊列)、deQueue (元素出隊列)、isQueueEmpty (判斷隊列是否爲空,空返回1,不空返回0)。
分析
棧的特點是後進先出,隊列的特點是先進先出。所以,當用兩個棧sI和s2模擬一個隊列時,sI作爲輸入棧,逐個元素壓棧,以此模擬隊列元素的入隊。當需要出隊時,將棧sI退棧並逐個壓入棧s2中,sI中最先入棧的元素在s2中處於棧頂。s2退棧,相當於隊列的出隊,實現了先進先出。只有棧s2爲空且sI也爲空時,纔算是隊列空。
代碼
核心代碼:
/* 入隊列 */
/* &s1指的是棧1;&s2指的是棧2;x指的是要入隊列的元素 */
int enQueue(SqStack &s1,SqStack &s2,int x) {
int y;
if(s1.top==maxSize-1) { // 若棧s1滿,則看s2是爲空
if(!isEmpty(s2)) {
return 0;// s1滿、s2非空,這時s1不能入棧,s2也不能入棧,因爲棧的特點是先進後出
} else if(isEmpty(s2)) { // 若s1滿、s2爲空,則將s1退棧,將元素壓入到s2中
while(!isEmpty(s2)) {
pop(s1,y);
push(s2,y);
}
push(s1,x);// 將棧s1所有元素壓入s2中,再將新元素壓入s1中,這就實現了元素的入隊
return 1;
}
} else {
push(s1,x);// 若s1沒有滿,則x直接入棧,返回1
return 1;
}
}
/* 出隊列 */
/* &s1指的是棧1;&s2指的是棧2;x指的是要出隊列的元素 */
int deQueue(SqStack &s1,SqStack &s2,int &x) {
int y;
if(!isEmpty(s2)) { // 棧2不空,則直接出隊,返回1
pop(s2,x);
return 1;
} else { // 處理s2空棧
if(isEmpty(s1)) { // 若輸入棧也爲空,則判定隊空,返回0
return 0;
} else { // 先將棧s1倒入s2中,再做出隊操作
while(!isEmpty(s1)) {
pop(s1,y);
push(s2,y);
}
pop(s2,x);// 然後s2退棧,實現隊出隊
return 1;
}
}
}
/* 判斷是否隊空 */
int isQueueEmpty(SqStack s1,SqStack s2) {
if(isEmpty(s1)&&isEmpty(s2)) {
return 1;// 隊列空
} else {
return 0;// 隊列不空
}
}
完整代碼:
#include <stdio.h>
#define maxSize 20
typedef struct {
int data[maxSize];// 存放棧中元素,maxSize是已經定義好的常量
int top;// 棧頂指針
} SqStack; // 順序棧類型定義
/* 初始化順序棧 */
/* &st指的是要操作的順序棧 */
void initStack(SqStack &st) {
st.top=-1; // 只需將棧頂指針設置爲-1,本棧中將top=-1規定爲棧空狀態
}
/* 判斷棧空 */
/* st指的是要進行判空的順序棧 */
int isEmpty(SqStack st) {
// 棧爲空的時候返回1,否則返回0
if(st.top==-1) { // 判空的條件是棧頂指針是否等於-1
return 1;
} else {
return 0;
}
}
/* 判斷棧滿 */
/* st指的是要進行判滿的順序棧 */
int isFull(SqStack st) {
// 如果棧頂指針等於maxSize-1那麼棧滿,否則棧空
if(st.top==maxSize-1) { // maxSize是棧中最大元素個數,已經定義
return 1;// 棧滿返回1
} else {
return 0;// 棧空返回0
}
}
/* 進棧 */
/* &st指的是要操作的棧;x指的是要進棧的數據 */
int push(SqStack &st,int x) {
/* 進棧首先要判斷棧是否棧滿,如果滿棧則不能進棧 */
if(isFull(st)==1) {
return 0;// 如果棧滿返回0,表示不能進棧
} else {
// 注意:++top和top++在這裏的作用是一樣的,都可以使用,如果是a=++top和a=top++,那麼兩個a的值是不一樣的,最後top的值還是一樣
++st.top;// 先移動指針,再進棧
st.data[st.top]=x;
return 1;// 進棧成功返回1
}
}
/* 出棧 */
/* &st指的是要操作的棧;&x指的是要出棧的數據 */
int pop(SqStack &st,int &x) {
/* 出棧之前要判斷棧是否爲空 */
if(isEmpty(st)==1) {// 1表示棧空,0表示非空
return 0;// 如果棧空,不能出棧,返回0
} else {
x=st.data[st.top];// 先取出元素,再出棧
--st.top;
return 1;// 出棧成功返回1
}
}
/* 打印棧,從左到右表示棧底到棧頂 */
/* stack表示要被打印的棧 */
void printStack(SqStack stack) {
printf("\n");
for(int i=0; i<=stack.top; i++) {// 注意:data[0]表示棧底元素,data[top]表示棧頂元素
printf("%d\t",stack.data[i]);// 打印棧中元素
}
printf("\n");
}
/* 入隊列 */
/* &s1指的是棧1;&s2指的是棧2;x指的是要入隊列的元素 */
int enQueue(SqStack &s1,SqStack &s2,int x) {
int y;
if(s1.top==maxSize-1) { // 若棧s1滿,則看s2是爲空
if(!isEmpty(s2)) {
return 0;// s1滿、s2非空,這時s1不能入棧,s2也不能入棧,因爲棧的特點是先進後出
} else if(isEmpty(s2)) { // 若s1滿、s2爲空,則將s1退棧,將元素壓入到s2中
while(!isEmpty(s2)) {
pop(s1,y);
push(s2,y);
}
push(s1,x);// 將棧s1所有元素壓入s2中,再將新元素壓入s1中,這就實現了元素的入隊
return 1;
}
} else {
push(s1,x);// 若s1沒有滿,則x直接入棧,返回1
return 1;
}
}
/* 出隊列 */
/* &s1指的是棧1;&s2指的是棧2;x指的是要出隊列的元素 */
int deQueue(SqStack &s1,SqStack &s2,int &x) {
int y;
if(!isEmpty(s2)) { // 棧2不空,則直接出隊,返回1
pop(s2,x);
return 1;
} else { // 處理s2空棧
if(isEmpty(s1)) { // 若輸入棧也爲空,則判定隊空,返回0
return 0;
} else { // 先將棧s1倒入s2中,再做出隊操作
while(!isEmpty(s1)) {
pop(s1,y);
push(s2,y);
}
pop(s2,x);// 然後s2退棧,實現隊出隊
return 1;
}
}
}
/* 判斷是否隊空 */
int isQueueEmpty(SqStack s1,SqStack s2) {
if(isEmpty(s1)&&isEmpty(s2)) {
return 1;// 隊列空
} else {
return 0;// 隊列不空
}
}
int main() {
SqStack stack1,stack2;
initStack(stack1);/* 初始化棧 */
initStack(stack2);
enQueue(stack1,stack2,1);// 將元素1壓入棧中
enQueue(stack1,stack2,2);
enQueue(stack1,stack2,3);
enQueue(stack1,stack2,4);
enQueue(stack1,stack2,5);
enQueue(stack1,stack2,6);
int x;
deQueue(stack1,stack2,x);// 出棧
printf("%d",x);
return 0;
}
運行結果: