浙大PTA-数据结构与算法题目集(中文)-7-22 堆栈模拟队列
·
题干:

样例输入输出:

解题思路:
题目说的很清晰了,就是用两个栈模拟队列。这里最核心的思想就是要清楚栈和队列的特性是什么。其次,我们要选择一个栈作为输入栈一个作为输出栈,为什么???其实,如果只是为了模拟队列,我们不需要考虑很多,只需要满足先进先出的特性即可,不必区分哪个栈输入哪个栈输出。
比方说,我们可以:(这里定义s1为输入栈,s2为输出栈)
入队操作时
- 判断随意选择的输入栈s1是否为满,不满可以直接入栈
- 当s1满时,若s2为空,可以先将s1中的元素转移到s2中,然后s1入栈(这样做是为了不破坏数据的正确输入输出顺序,而如果s1满且s2不为空时,此时再入栈,就要将s1中的栈顶元素出栈并压入s2。但是,如果这样做,因为我们模拟的是队列,s2原来栈顶的元素本来应该作为队头元素首先出队,但是你这样压入了s1的元素,就完全破坏了队列的特性)
- 当s1满时,并且s2中不为空,则无法入栈(原因在2中已有说明)
出队操作时
- 当s2中有元素时可以直接出栈
- 当s2中为空时,将s1中的元素转移到s2中
- s1与s2都为空,则无法出栈 (出队操作逻辑比较简单)
这样子,我们就完成了这道题吗?
相信有同学和我一样,就这样提交上去,发现答案全错???
这里大家要注意的是,题目中要求的ERROR信息,这是一个很关键的地方,题目中所要求的队空和堆满ERROR都是在性能最优的情况先考虑的,也就是说我们上面的解决方法不是最优解,在我们的方法中队空队满都是假队空队满。如果换一种方法,还是可以放进去元素,或是元素出队的。
这里告诉大家,最优解就是,容量较小的作为输入栈s1,而容量大的则作为输出栈s2。这个原理其实并不难理解,大家仔细想想就理解了,这里就不赘述了。。。
最终代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Stack{
int *data;
int top;
int capacity;
}Stack;
Stack* createStack(int max){
Stack *s = (Stack*)malloc(sizeof(Stack));
s->data = (int*)malloc(max*sizeof(int));
s->top = -1;
s->capacity = max;
return s;
}
int isFull(Stack *s){
return s->top == s->capacity-1;
}
int isEmpty(Stack *s){
return s->top == -1;
}
int Push(Stack *s,int item){
if(isFull(s)) return 0;
s->data[++(s->top)] = item;
return 1;
}
int Pop(Stack *s,int *item){
if(isEmpty(s)) return 0;
*item = s->data[(s->top)--];
return 1;
}
typedef struct{
Stack *s1;
Stack *s2;
int capacity1;
int capacity2;
}Queue;
Queue* initQueue(int n1,int n2){
Queue *q = (Queue*)malloc(sizeof(Queue));
q->s1 = createStack(n1);
q->s2 = createStack(n2);
q->capacity1 = n1;
q->capacity2 = n2;
return q;
}
void AddQ(Queue *q,int item){
//当s1不为满时,直接入栈
if(!isFull(q->s1)){
Push(q->s1,item);
return;
}
//当s1满时,若s2为空,可以先将s1中的元素转移到s2中,然后s1入栈
if(isFull(q->s1) && isEmpty(q->s2)){
int data;
while(Pop(q->s1,&data)!=0){
Push(q->s2,data);
}
Push(q->s1,item);
return;
}
//当s1满时,并且s2中不为空,则无法入栈
if(isFull(q->s1) == 1 && isEmpty(q->s2)!=1){
printf("ERROR:Full\n");
return;
}
}
int Delete(Queue *q){
//当s2中有元素时可以直接出栈
if(isEmpty(q->s2)==0){
int data;
if(Pop(q->s2,&data) == 1){
return data;
}
}
//当s2中为空时,将s1中的元素转移到s2中
if(isEmpty(q->s2)==1 && isEmpty(q->s1)!=1){
int data;
while(Pop(q->s1,&data)!=0){
Push(q->s2,data);
}
Pop(q->s2,&data);
return data;
}
if(isEmpty(q->s1)&&isEmpty(q->s2)){
printf("ERROR:Empty");
return 99999;
}
}
int main(){
char cmd;
int num;
int n1,n2;
scanf("%d %d",&n1,&n2);
int min,max;
if(n1<n2){
min = n1;
max = n2;
}else{
min = n2;
max = n1;
}
Queue *q = initQueue(min,max);
getchar();
while(scanf("%c",&cmd)==1&&cmd!='T'){
if(cmd=='A'){
scanf("%d",&num);
AddQ(q,num);
}
if(cmd=='D'){
int data = Delete(q);
if(data!=99999){
printf("%d\n",data);
}
}
}
return 0;
}
AC

更多推荐
所有评论(0)