《剑指offer》:[6]两个栈实现一个队列的C++代码实现
2016-05-26 11:16
761 查看
问题:用两个栈实现一个队列,完成在队列尾部插入节点和在队列头部删除结点的功能。
由于栈的特点是先进后出,要想实现队列,必须做到先进先出;
首先将数据输入到stack1中,这时候先进后出,再将stack1中的数据移动到stack2中,相当于将输入的数据的顺序颠倒,这样也就实现了队列的特点,先进先出。下面具体说一下队列为NULL,入队和出队的具体实现方法;
(1)判断队列是否为NULL:stack1==NULL && stack2==NULL,则队列为空;
(2)出队:如果stack1为NULL,stack2不为NULL,从stack2中直接出栈,也就是出队列;
如果stack1不为NULL,将stack1的数据出栈到stack2中,从stack2中直接出栈,也就是出队列;
(3)入队:如果stack2为NULL,直接入栈stack1,也即入队列;
如果stack2不为NULL,将stack2出栈到stack1中,数据入栈stack1,也即入队列;
示意图如下所示:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201605/9327aae25f6be0b9ef2331cf096d888f)
总之:我们规定stack1是入队栈,stack2是出队栈;反之也可以,这个比较随意。
改进之处:出队时候:如果stack1不为NULL,此时需要将stack1中的元素移动到stack2中,其实不需要全部移完,如果移到stack1中只有一个元素的时候,就直接可以出栈,不需要将最后一个元素移动到stack2中,再在stack2中出栈;入栈也一样可以避免一次入栈和出栈,这对于频繁入栈出栈的程序可以大大提高它的效率。
实现一:利用容器。具体代码如下:
运行结果:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201605/354f10646bfeb0dedb0f79543040bb0f)
方案二:链表实现栈:
由于栈的特点是先进后出,要想实现队列,必须做到先进先出;
首先将数据输入到stack1中,这时候先进后出,再将stack1中的数据移动到stack2中,相当于将输入的数据的顺序颠倒,这样也就实现了队列的特点,先进先出。下面具体说一下队列为NULL,入队和出队的具体实现方法;
(1)判断队列是否为NULL:stack1==NULL && stack2==NULL,则队列为空;
(2)出队:如果stack1为NULL,stack2不为NULL,从stack2中直接出栈,也就是出队列;
如果stack1不为NULL,将stack1的数据出栈到stack2中,从stack2中直接出栈,也就是出队列;
(3)入队:如果stack2为NULL,直接入栈stack1,也即入队列;
如果stack2不为NULL,将stack2出栈到stack1中,数据入栈stack1,也即入队列;
示意图如下所示:
总之:我们规定stack1是入队栈,stack2是出队栈;反之也可以,这个比较随意。
改进之处:出队时候:如果stack1不为NULL,此时需要将stack1中的元素移动到stack2中,其实不需要全部移完,如果移到stack1中只有一个元素的时候,就直接可以出栈,不需要将最后一个元素移动到stack2中,再在stack2中出栈;入栈也一样可以避免一次入栈和出栈,这对于频繁入栈出栈的程序可以大大提高它的效率。
实现一:利用容器。具体代码如下:
#include<iostream> #include <algorithm> #include <stack> #include <queue> using namespace std; stack<int> s1; stack<int> s2; void InQueue(int number)//入队 { if(s2.empty()) { s1.push(number);//stack1入栈,即入栈; cout<<"InQueue:"<<number<<endl; return; } while(!s2.empty()) { s1.push(s2.top()); s2.pop(); } s2.push(number); cout<<"InQueue:"<<number<<endl; /*这里为什么而是stack2入队?这主要是做了一个改进,其实和上面的步骤(1)(2)(3)不矛盾,因为stack1是入队栈,number进入stack1后可能马上就要出栈,所以又要将stack1中的数据移动到stack2中,所以避免了一个数据的入栈和出栈,提高了效率;*/ } void OutQueue() { if(s1.empty())//s2出栈,即出队; { cout<<"OutQueue:"<<s2.top()<<endl; s2.pop(); return; } while(s1.size()>1) { s2.push(s1.top()); s1.pop(); } cout<<"OutQueue:"<<s1.top()<<endl; s1.pop(); /*这里为什么而是stack1队队?这主要也是做了一个改进,同样和上面的步骤(1)(2)(3)不矛盾。因为stack2是出队栈,stack1中的number进入stack2后马上就要出栈,所以当stack1中只剩下一个元素的时候就是出栈的数据,就不必入栈stack2,同样也是避免了一个数据的入栈和出栈,提高了效率;*/ } bool IsEmpty()//判断队列是否为NULL; { if(s1.empty() && s2.empty()) return 1; else return 0; } int main() { int array[]={1,2,3}; for(int i=0;i<3;i++) { InQueue(array[i]); //全部入队:1,2,3; } for(int i=0;i<3;i++) { if(IsEmpty()) //判断是否为NULL; return NULL; OutQueue(); //全部出队:1,2,3; } system("pause"); return 0; }
运行结果:
方案二:链表实现栈:
#include<iostream> using namespace std; typedef struct My_Stack { int number; My_Stack*next; }stack1,stack2; stack1 *pHead1=NULL; stack2 *pHead2=NULL; My_Stack *pEnd=NULL; My_Stack *pNode=NULL; void instack(My_Stack **phead,int data) { pNode=new My_Stack; pNode->number=data; pNode->next=NULL; if(NULL==*phead) { *phead=pNode; pEnd=pNode; } else { pNode->next=*phead; *phead=pNode; } } int outstack(My_Stack **phead) { My_Stack *temp=(*phead); int number=0; if(*phead) { (*phead)=(*phead)->next; number=temp->number; delete temp; temp=NULL; return number; } return NULL; } void InQueue(My_Stack **phead1,My_Stack **phead2,int data)//入队 { if(NULL==(*phead2)) { instack(phead1,data);//stack1入栈,即入栈; cout<<"NN-InQueue:"<<data<<endl; return; } while(*phead2) { instack(phead1,outstack(phead2)); } instack(phead2,data); cout<<"NN-InQueue:"<<data<<endl; } void OutQueue(My_Stack **phead1,My_Stack **phead2) { if(NULL==*phead1)//s2出栈,即出队; { cout<<"NN-OutQueue:"<<outstack(phead2)<<endl; return; } while(*phead1) { instack(phead2,outstack(phead1)); } cout<<"NN-OutQueue:"<<outstack(phead2)<<endl; } bool IsEmpty()//判断队列是否为NULL; { if( !pHead1 && !pHead2) return 1; else return 0; } int main() { int array[]={1,2,3}; for(int i=0;i<3;i++) { InQueue(&pHead1,&pHead2,array[i]); //全部入队:1,2,3; } for(int i=0;i<3;i++) { if(IsEmpty()) //判断是否为NULL; return NULL; OutQueue(&pHead1,&pHead2); //全部出队:1,2,3; } system("pause"); return 0; }运行结果:
相关文章推荐
- JS中完美兼容各大浏览器的scrolltop方法
- Data获取字节数据,组成字符串出错 rapidjson解析出错
- HTIML5 真的打败了Flash?新测试结果出人意料
- JS中语句的另类写法。
- 来看看css3中的box-shadow
- Javascript 严格模式详解
- Installation error: INSTALL_PARSE_FAILED_MANIFEST_MALFORMED
- ReactNative-----环境搭建二(android)
- js前台判断开始时间是否小于结束时间
- caffe中forward过程总结
- angularJS中的核心服务深入理解
- JS 学习计算器编写
- WORD2007转HTML
- 解决jQuery插件重名问题
- Web版 扫雷 JS实现
- HTML5 本地裁剪图片并上传至服务器 canvas图片上传 canvas图片裁剪
- jquery实现动画伸缩效果
- css3之渐变
- 循环取到json中的字段数据,加到html中
- [Flex] IFrame系列 —— 嵌入本地页面两种方式source和content(html页面和html代码)