面试题:用两个栈实现队列&用两个队列实现栈
来源:互联网 发布:pls tower 软件 购买 编辑:程序博客网 时间:2024/06/13 22:58
用两个栈实现一个队列
1、要求:一个队列包含两个栈stack1和stack2,用这两个“先进后出”的栈实现一个“先进先出”的队列queue,主要实现appendTail和deleteHead函数。
2、思路:首先向stack1压入元素a、b和c,则stack1中元素有{a,b,c},其中c位于栈顶,而stack2是空的。
这时,要从队列中删除一个元素,按照队列先入先出的规则,由于a比b、c先插入到队列中,最先被删除的元素应该是a。元素a在stack1中,但并不在栈顶,因此不能直接删除。如果把stack1中的元素逐个弹出并压入stack2,元素在stack2中的顺序正好和原来在stack1中的顺序相反。因此经过3次弹出stack1和压入stack2操作结束之后,stack1为空,而stack2中的元素为{c,b,a},这个时候就可以弹出stack2的栈顶元素a了。
如果要继续删除队列的头部,剩下的两个元素b和c,b比c早进入队列,因此b先删除,而此时b恰好在栈顶上,因此直接弹出stack2的栈顶即可。这次弹出操作之后,stack1中任然为空,而stack2为{c}。
接下来再插入一个元素d,还是把它压入stack1,如果下一次要删除队列头部的元素,因为stack2不为空,可以直接弹出它的栈顶元素c,而串的确是比d先进入队列,应该在d之前在队列中删除,因此不会出现任何矛盾。
具体的插入和删除操作如图所示:
小结:队列中插入元素只插入到stack1的栈顶,删除元素只从stack2的栈顶删除,当stack2中不为空时,在stack2中的栈顶元素是最先进入队列的元素,可以弹出。如果stack2为空时,先把stack1中元素逐个压入stack2.由于先进入队列的元素被压入到stack1的低端,经过弹出和压入之后就处于stack2的顶端了,则可以直接弹出。
代码实现:
//尾插void appendTail(stack<int> *stack1,int data){ stack1->push(data);}//头删void deleteHead(stack<int> *stack1,stack<int> *stack2,int *val){ if (stack2->size()<=0) { while (s1->size()>0) { int data = stack1->top(); stack1->pop(); stack2->push(data); } } if (stack2->size()==0) { printf("queue is empty\n"); return; } *val = stack2->top(); stack2->pop();}
用两个队列实现一个栈
1、要求:一个栈包含两个队列queue1和queue2,用这两个“先进先出”的队列实现一个“先进后出”的栈stack,主要实现Top、Push和Pop三个函数。
2、思路:先往一个栈内压入一个元素a。由于两个队列现在都是空的,可以把a插入两个队列中的任意一个。不妨插入queue1.接下来继续往栈内压入b、c两个元素,把它们都插入queue1。这时,queue1包含3个元素a、b和c,其中a位于队列的头部,c位于队列的尾部。
然后从栈内弹出一个元素。根据栈的先入后出原则,最后被压入栈的c应该最先被弹出。由于c位于queue1的尾部,而每次只能从队列的头部删除元素,因此可以先从queue1中依次删除元素a、b并插入到queue2中,再从queue1中删除元素c。这就相当于从栈中弹出元素c了。可以用同样的方法从栈内弹出元素b。
接下来再往栈内压入一个元素d。此时queue1已经有一个元素a,就把d插入queue1的尾部。如果再从栈内弹出一个元素,此时被弹出的应该是最后被压入的d。由于d位于queue1的尾部,只能先从头部删除queue1的元素a并压入到队列queue2中,直到queue1中遇到d再直接把它删除。
具体的插入和删除算法如图所示:
小结:往栈顶插入元素时,如果有一个队列中有元素,则插入该队列的尾部,如果没有,可以任选一个插入;从栈顶删除元素时,如果有一个队列中元素不为空,则依次先将队头元素删除并插入另一个队列中,直到该队列中留下最后一个元素,则获取该元素的值,并将它出队。
代码实现:
//压栈void Push(queue<int> *queue1,queue<int> *queue2,int data){ if(queue1->size() == 0 && queue2->size() != 0) { queue<int> *temp = queue1; queue1 = queue2; queue2 = temp; } queue1->push(data);}//出栈void Pop(queue<int> *queue1,queue<int> *queue2,int *val){ if (queue1->size()+queue2->size()==0) { printf("stack is empty\n"); return; } else if(queue1->size()==0) { queue<int> *temp = q1; q1 = q2; q2 = temp; } //将先进去的元素顺序压入另一个队列,并出队,最后只剩下一个元素,然后出队 while (queue1->size()>1) { int temp = queue1->front();//获取队首元素 queue2->push(temp); queue1->pop(); } *val = queue1->front(); queue1->pop();}//获取栈顶元素void Top(queue<int> queue1,queue<int> queue2,int *val){ if (queue1.size()+queue2.size()==0) { printf("stack is empty\n"); return; } else if(q1.size()==0) { *val = q1.back();//获取队列的队尾元素 } else { *val = q2.back();//获取队列的队尾元素 }}
测试代码:
#include <stdio.h>#include <stack>#include <queue>using namespace std;int main(){ //两个栈实现一个队列 stack<int> s1,s2; int i; for (i=0;i<3;++i) { appendTail(&s1,i+1); } appendTail(&s1,5); printf("queue--------size:%d\n",s1.size()+s2.size()); int data; deleteHead(&s1,&s2,&data); printf("delete_data-------%d\n",data); printf("queue--------size:%d\n",s1.size()+s2.size()); //两个队列实现一个栈 queue<int> q1,q2; for (i=0;i<5;++i) { Push(&q1,2*i+1); } int val; Pop(&q1,&q2,&val); Pop(&q1,&q2,&val);// Pop(&q1,&q2,&val); Top(q1,q2,&val); printf("length:%d\n",q1.size()+q2.size()); printf("val:%d\n",val);}
- 面试题7:用两个栈实现队列和用两个队列实现栈
- 面试题7:用两个栈实现队列和用两个队列实现一个栈
- 面试题7:用两个栈实现队列+用两个队列实现栈
- 剑指Offer面试题7用两个栈实现队列(附带用两个队列实现栈)
- 面试题:用两个栈实现队列&用两个队列实现栈
- 面试题13 - 用两个栈实现队列 【栈】
- 面试题--用两个栈实现一个队列
- 面试题研究 用两个栈模拟实现队列
- 剑指offer-->面试题7 用两个栈实现队列
- 经典面试题一:用两个栈实现一个队列
- 面试题7:用两个栈实现队列
- 面试题6:用两个栈实现队列
- 面试题7:用两个队列实现栈
- [剑指offer][面试题07]用两个栈实现队列
- 《剑指Offer》面试题-用两个栈实现队列
- 《剑指offer》面试题七 用两个栈实现队列
- 面试题7 用两个栈实现队列
- 面试题 用两个栈实现一个队列
- CSocket如何通知窗口(MFC)
- is not in the sudoers file.This incident will be reported
- to_char跟to_date
- window.open父子窗口数据传递问题
- 前辈写码需谨慎,接手开发很头疼
- 面试题:用两个栈实现队列&用两个队列实现栈
- 查漏补缺
- 进程、线程、协程 关于进程、线程、协程,有非常详细和丰富的博客或者学习资源,我不在此做赘述,我大致在此介绍一下这几个东西。 进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度。
- mysql数据库的优化整理之数据库结构优化
- Hibernate基础学习(二)—Hibernate相关API介绍
- Java实现更改文件路径
- 2000-一维整形数组
- Android在网页中打开app并传递数据
- 机器学习实战_08预测数值型数据-回归