转载请注明出处:http://blog.csdn.net/ns_code/article/details/22509253
题目:
Implement a MyQueue class which implements a queue using two stacks.
翻译:
使用两个栈实现一个队列MyQueue。
思路:两个栈模拟一个队列,主要是用两个栈的push和pop操作来实现队列的enter和delete操作。不难想到如下实现思路:
执行入队操作时,将数据压入到栈1中,这时,队首元素位于栈1的栈底,执行出队操作时,将数据从栈1中逐个弹出,边弹边压入到栈2中,这样,当栈1中的数全部pop出来后,栈2的栈顶元素即为队列的队首元素。如果栈2的数全部出队了,也就是栈2为空了,怎么办?继续将栈1的元素全部pop出来,逐个push到栈2中。我们总结规律如下:
执行入队操作时,只需将元素逐个压入到栈1中,不用管栈2,执行出队操作时,如果栈2不空,则将直接将栈2的元素出栈即可,如果栈2为空,则将栈1中的元素全部pop出来,逐个push到栈2中,再执行栈2的出栈操作。这里面要注意出队边界情况的判断,当栈2和栈1均为空时,说明队列为空,没有元素可以pop了,如果此时执行pop操作,要return false。另外,这里稍微可以做一点点优化,就是在执行出队操作时,如果栈2为空,我们需要将栈1中的元素出栈,压入到栈2中,但是栈1的栈底元素即为要出队的元素,所以我们可以直接将其弹出,而不再压入栈2中,这样少了一组push和pop操作。
PS:以上思路已经过滤掉了多余的push和pop操作,已经是执行效率最好的操作了!
代码如下:
/* 用两个栈模拟入队 */ void enter_Queue(PSTACK pS1,int val) { push_stack(pS1,val); } /* 用两个栈模拟出队 */ bool delete_Queue(PSTACK pS1,PSTACK pS2,int *pData) { if(is_empty(pS1) && is_empty(pS2)) return false; if(!is_empty(pS2)) pop_stack(pS2,pData); else if(!is_empty(pS1)) { while(!is_empty(pS1)) { int pS1_popData; pop_stack(pS1,&pS1_popData); push_stack(pS2,pS1_popData); } pop_stack(pS2,pData); } return true; }由于博主队STL不是很熟,这里用到了自己以前写stack的相关操作,完整代码如下:
/******************* 题目描述: 用两个栈实现一个队列 Data:2014-03-29 ********************/ /************************************************************************************************************** 以下为操作栈的算法,该栈为动态栈。 在该栈中,pTop指向的节点中存放该栈的栈顶数据 pBottom指向的节点的上一个节点存放该栈的栈底数据,pBottom指向的节点中不存放有效数据, 这样做的目的是为了在进行入栈和出栈时方便对栈的操作,而用考虑特殊情况 **************************************************************************************************************/ #include<stdio.h> #include<stdlib.h> typedef struct Node { int data; struct Node *pNext; }NODE,*PNODE; typedef struct Stack { PNODE pTop; PNODE pBottom; }STACK,*PSTACK; PSTACK create_stack(); void push_stack(PSTACK,int); void traverse_stack(PSTACK); bool pop_stack(PSTACK,int *); bool is_empty(PSTACK); void clear_stack(PSTACK); void enter_Queue(PSTACK,int); bool delete_Queue(PSTACK,PSTACK,int *); int main() { int data_pop; //创建一个空的栈,pS指针指向该栈 PSTACK pS1 = create_stack(); PSTACK pS2 = create_stack(); enter_Queue(pS1,1); enter_Queue(pS1,2); enter_Queue(pS1,3); delete_Queue(pS1,pS2,&data_pop); printf("The pop data:%d\n",data_pop); delete_Queue(pS1,pS2,&data_pop); printf("The pop data:%d\n",data_pop); enter_Queue(pS1,4); enter_Queue(pS1,5); delete_Queue(pS1,pS2,&data_pop); printf("The pop data:%d\n",data_pop); enter_Queue(pS1,6); delete_Queue(pS1,pS2,&data_pop); printf("The pop data:%d\n",data_pop); delete_Queue(pS1,pS2,&data_pop); printf("The pop data:%d\n",data_pop); delete_Queue(pS1,pS2,&data_pop); printf("The pop data:%d\n",data_pop); return 0; } /* 创建一个空栈,并返回指向该栈的指针 */ PSTACK create_stack() { PSTACK pS = (PSTACK)malloc(sizeof(STACK)); pS->pTop = (PNODE)malloc(sizeof(NODE)); if(NULL==pS || NULL==pS->pTop) { printf("malloc failed"); exit(-1); } else { pS->pBottom = pS->pTop; pS->pBottom->pNext = NULL; } return pS; } /* 判断该栈是否为空 */ bool is_empty(PSTACK pS) { if(pS->pTop == pS->pBottom) return true; else return false; } /* 向pS指针指向的栈中压入数据val */ void push_stack(PSTACK pS,int val) { PNODE pNew = (PNODE)malloc(sizeof(NODE)); if(NULL==pNew) { printf("malloc failed"); exit(-1); } else { pNew->data = val; pNew->pNext = pS->pTop; pS->pTop = pNew; } return ; } /* 从栈中推出数据,并将推出的数据保存在pData指针所指向的位置 */ bool pop_stack(PSTACK pS,int *pData) { if(is_empty(pS)) return false; else { PNODE p = pS->pTop; *pData = p->data; pS->pTop = p->pNext; free(p); p = NULL; return true; } } /* 遍历栈,并自栈顶向栈底输出栈中的数据 */ void traverse_stack(PSTACK pS) { PNODE pCurrent = pS->pTop; printf("Now datas int the stack are:\n"); while(pCurrent != pS->pBottom) { printf("%d ",pCurrent->data); pCurrent = pCurrent->pNext; } printf("\n"); return ; } /* 清空栈,即将其还原为空栈 */ void clear_stack(PSTACK pS) { if(is_empty(pS)) return ; else { PNODE p = pS->pTop; PNODE r = NULL; while(p != pS->pBottom) { r = p->pNext; free(p); p = r; } pS->pTop = pS->pBottom; } } /* 用两个栈模拟入队 */ void enter_Queue(PSTACK pS1,int val) { push_stack(pS1,val); } /* 用两个栈模拟出队 */ bool delete_Queue(PSTACK pS1,PSTACK pS2,int *pData) { if(is_empty(pS1) && is_empty(pS2)) return false; if(!is_empty(pS2)) pop_stack(pS2,pData); else if(!is_empty(pS1)) { while(!is_empty(pS1)) { int pS1_popData; pop_stack(pS1,&pS1_popData); push_stack(pS2,pS1_popData); } pop_stack(pS2,pData); } return true; }测试结果:
注:代码开源到Github:https://github.com/mmc-maodun/CareerCup
【CareerCup】Stacks and Queues—Q3.4,布布扣,bubuko.com
【CareerCup】Stacks and Queues—Q3.4
原文:http://blog.csdn.net/ns_code/article/details/22509253