Algorithm --> 两个栈实现队列和两个队列实现栈
两个栈实现队列和两个队列实现栈
队列(queue)先进先出的线性表;栈(stack)先进后出的线性表。
两个栈实现队列
法一思路:
s1是入栈的,s2是出栈的。
- 入队列:直接压入s1即可;
- 出队列:如果s2不为空,把s2中的栈顶元素直接弹出;否则,把s1的所有元素全部弹出压入s2中,再弹出s2的栈顶元素。
代码:
#include <stack>
#include <iostream>
#include <cassert>
using namespace std; template <class T>
class Queue {
public:
bool empty( ) const { return m_stack1.empty() && m_stack2.empty(); }
size_t size( ) const { return m_stack1.size() + m_stack2.size(); }
void push( const T& x );
void pop( );
private:
stack<T> m_stack1;
stack<T> m_stack2;
}; template <class T>
void Queue<T>::push( const T& x )
{
m_stack1.push( x );
} template <class T>
void Queue<T>::pop( )
{
// if m_stack2 is empty, and there are some elements in m_stack1, push them in m_stack2
if( m_stack2.empty() ) {
while( !m_stack1.empty() ) {
T& data = m_stack1.top( );
m_stack1.pop( );
m_stack2.push( data );
}
}
// push the element into m_stack2
assert( !m_stack2.empty() );
m_stack2.pop( );
} int main( )
{
Queue<int> q;
for( int i = ; i <= ; ++i )
q.push( i );
q.pop( );
q.push( );
q.pop( );
q.pop( );
q.push( );
q.pop( );
q.pop( );
q.pop( );
q.pop( ); return ;
}
法二思路:
用两个栈来实现,令其中一个栈inStack专门处理入队工作,另一个栈outStack专门处理出队工作。
- 入队列:直接把元素加入到 inStack中,复杂度为O(1);
- 出队列:因为队列是先入先出的,而栈是先入后出,所以输出应该反序。比如inStack接收到的元素顺序为1, 2, 3,栈顶元素是3,但出队希望让1先出。解决方法是把inStack里的元素放到outStack中,这样outStack接收到的元素顺序就是3, 2, 1了,栈顶元素就是我们想要的1,时间复杂度为O(N)。
总结,入队直接inStack.push(元素),出队先判断outStack是否为空,若不为空,则直接outStack.pop(),若为空,则把inStack元素导入到outStack里,再执行outStack.pop()。
#include <stack>
#include <string>
#include <iostream>
#include <cassert> using namespace std; template <class T>
class YL_Queue
{
public:
void enqueue(const T &element); //入队
T dequeue(); //出队
T top(); //队首元素
bool empty() const; //判断队列是否为空
size_t size() const; //队列的尺寸大小
private:
stack<T> inStack;
stack<T> outStack;
}; template <class T>
void YL_Queue<T>::enqueue(const T &element)
{
inStack.push(element);
} template <class T>
T YL_Queue<T>::dequeue()
{
assert(!empty()); T temp;
if (!outStack.empty())
{
temp=outStack.top();
outStack.pop();
return temp;
}
else
{
while(!inStack.empty())
{
temp=inStack.top();
inStack.pop();
outStack.push(temp);
}
temp= outStack.top();
outStack.pop();
return temp;
}
} template <class T>
T YL_Queue<T>::top()
{
assert(!empty()); T temp;
if (!outStack.empty())
{
temp=outStack.top();
return temp;
}
else
{
while(!inStack.empty())
{
temp=inStack.top();
inStack.pop();
outStack.push(temp);
}
temp= outStack.top();
return temp;
}
} template <class T>
bool YL_Queue<T>::empty() const
{
return (size()==);
} template <class T>
size_t YL_Queue<T>::size() const
{
return inStack.size()+outStack.size();
}
void main()
{
YL_Queue<int> myqueue;
myqueue.enqueue();
myqueue.enqueue();
myqueue.enqueue();
myqueue.enqueue();
myqueue.enqueue();
cout<<"1队列的大小为: "<<myqueue.size()<<endl;
cout<<"1队首的元素为: "<<myqueue.top()<<endl;
myqueue.dequeue();
myqueue.dequeue();
cout<<"2队列的大小为: "<<myqueue.size()<<endl;
cout<<"2队首的元素为: "<<myqueue.top()<<endl;
myqueue.dequeue();
myqueue.dequeue();
myqueue.dequeue();
cout<<"3队列的大小为: "<<myqueue.size()<<endl;
}
两个队列实现栈
思路
s1是入队列的,s2是辅助s1入队列的。
- 入队列:如果s1不空,把s1的元素push到s2中,之后push新元素到s1,再把s2的元素都push到s1中;否则,直接push元素到s1
- 出队列:直接从s1中pop
代码:
#include <iostream>
#include <queue>
#include <cassert>
using namespace std; template <class T>
class Stack {
public:
bool empty( ) const { return m_queue1.empty() && m_queue2.empty(); }
size_t size( ) const { return m_queue1.size() + m_queue2.size(); }
T& top( );
const T& top( ) const;
void push( const T& x );
void pop( );
private:
queue<T> m_queue1;
queue<T> m_queue2;
}; template <class T>
T& Stack<T>::top( )
{
assert( !m_queue1.empty() );
return m_queue1.front( );
} template <class T>
const T& Stack<T>::top( ) const
{
assert( !m_queue1.empty() );
return m_queue1.front( );
} template <class T>
void Stack<T>::push( const T& x )
{
while( !m_queue1.empty() ) { //s1不空,把元素push到s2
const T& val = m_queue1.front( );
m_queue1.pop( );
m_queue2.push( val );
}
m_queue1.push( x ); //push新元素到s1
while( !m_queue2.empty() ) { //s2不空,把元素在push回s1
const T& val = m_queue2.front( );
m_queue2.pop( );
m_queue1.push( val );
}
} template <class T>
void Stack<T>::pop( )
{
assert( !m_queue1.empty() );
m_queue1.pop( );
} int main( )
{
Stack<int> s;
for( int i = ; i <= ; ++i )
s.push( i );
cout << "1.栈元素个数:" << s.size( ) << endl;
cout << "1.栈顶元素:" << s.top( ) << endl; s.pop( );
s.push( );
cout << "2.栈元素个数:" << s.size( ) << endl;
cout << "2.栈顶元素:"<< s.top( ) << endl; s.pop( );
s.pop( );
s.pop( );
s.push( );
cout << "3.栈元素个数:" << s.size( ) << endl;
cout << "3.栈顶元素:"<< s.top( ) << endl; s.pop( );
s.pop( );
s.pop( );
cout << "4.栈元素个数:" << s.size( ) << endl; return ;
}
Algorithm --> 两个栈实现队列和两个队列实现栈的更多相关文章
- 剑指offer 5.栈和队列 用两个栈实现队列
题目描述 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 解题思路:1,整体思路是元素先依次进入栈1,再从栈1依次弹出到栈2,然后弹出栈2顶部的元素,整个过程 ...
- 前、中、后序遍历随意两种是否能确定一个二叉树?理由? && 栈和队列的特点和区别
前序和后序不能确定二叉树理由:前序和后序在本质上都是将父节点与子结点进行分离,但并没有指明左子树和右子树的能力,因此得到这两个序列只能明确父子关系,而不能确定一个二叉树. 由二叉树的中序和前序遍历序列 ...
- [LeetCode] Binary Tree Level Order Traversal 与 Binary Tree Zigzag Level Order Traversal,两种按层次遍历树的方式,分别两个队列,两个栈实现
Binary Tree Level Order Traversal Given a binary tree, return the level order traversal of its nodes ...
- 算法与数据结构题目的 PHP 实现:栈和队列 由两个栈组成的队列
思路:同样使用 PHP 的数组模拟栈.栈的特点是先进后出,队列的特点是先进先出,可以用第一个栈(StackPush)作为压入栈,压入数据的时候只往这个栈中压入数据,第二个栈作(StackPop)为弹出 ...
- 包含MIN函数的栈+一个数组实现两个堆栈+两个数组实现MIN栈
1.题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数. 思路:利用一个辅助栈来存放最小值 栈 3,4,2,5,1 辅助栈 3,2,1 每入栈一次,就与辅 ...
- 使用java语言实现一个队列(两种实现比较)(数据结构)
一.什么是队列,换句话说,队列主要特征是什么? 四个字:先进先出 六个字:屁股进,脑袋出 脑补个场景:日常排队买饭,新来的排在后面,前面打完饭的走人,这就是队列: OK,思考一个问题,我为什么写了两种 ...
- Linux 进程间通信 消息队列 实现两个进程间通信
例子: 通过消息队列实现两个进程间通信,一个进程从终端输入数据,通过消息队列发送,另一个进程通过消息队列接收数据 文件1 创建进程1 终端输入通过消息队列发送数据 #include <stdio ...
- rabbitmq 实现延迟队列的两种方式
原文地址:https://blog.csdn.net/u014308482/article/details/53036770 ps: 文章里面延迟队列=延时队列 什么是延迟队列 延迟队列存储的对象肯定 ...
- Java数组实现循环队列的两种方法
用java实现循环队列的方法: 1.添加一个属性size用来记录眼下的元素个数. 目的是当head=rear的时候.通过size=0还是size=数组长度.来区分队列为空,或者队列已满. 2.数组中仅 ...
随机推荐
- 【linux】linux下网络的配置
linux网络的配置 一.配置网络vi /etc/sysconfig/network 配置网络vi /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE= ...
- Flex父子窗口相互调用
Flex父子窗口相互调用 1.设计思路 (1)子窗口调用父窗口的方法 (2)子窗口做了修改后,返回父窗口,父窗口调用子窗口函数 2.设计源码 (1)父窗口 ParentWindow.mxml: < ...
- IOS开发之XCode学习007:UIWindow对象
此文学习来源为:http://study.163.com/course/introduction/1002858003.htm #import "AppDelegate.h" @i ...
- 移动端开发底部元素margin-bottom失效解决办法
一.情景 记得之前开发一个微信端页面时,发现页面底部元素margin-bottom在ios下失效,在安卓内正常...... 1.safari浏览器内页面底部元素设置margin-bottom失效: 2 ...
- WPF基础篇之静态资源和动态资源
静态资源(StaticResource)指的是在程序载入内存时对资源的一次性使用,之后就不再访问这个资源了. 动态资源(DynamicResource)指的是在程序运行过程中然会去访问资源. 一.定义 ...
- [luogu3600]随机数生成器
题面在这里 题意 给定n个[1-x]的随机整数\(a_1,a_2,a_3,...,a_n\)和q个询问区间\((l_i,r_i)\), 求出\(\max_{i=1}^{q}({\min_{j=l_i} ...
- [BZOJ1050] [HAOI2006] 旅行comf (Kruskal, LCT)
Description 给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000).给你两个顶点S和T,求一条路径,使得路径上最大 ...
- Java对于特殊字符做间隔读入的处理(1.3.4)
先读进字符串,然后再用split分割,注意当默认间隔符有其他意义时,要用\转义字符转义 这道题是pat的一道题,主要读入方法看前面就行了 import java.util.Scanner; publi ...
- 【python学习笔记】3.字符串使用
[python学习笔记]3.字符串使用 字符串是一种序列,素有标准的序列操作对字符串用样适用,字符串是不可以改变 格式化操作符,%,左侧是格式化字符串,右侧是被格式的值,可以是一个值.元组.字典 数值 ...
- windows下编译caffe报错:error MSB4062: 未能从程序集 E:\NugetPackages\OpenCV.2.4.10\......的解决办法
参考博客:http://blog.csdn.net/u013277656/article/details/75040459 在windows上编译caffe时,用vs打开后会自动加载还原NugetPa ...