与栈相关的问题
1.设计一个栈,在其基础功能的基础上,设计一个getMin方法,每次调用时返回当前栈内的最小值。
要求:时间复杂度为O(1),可使用现成的栈结构。
思路:设计该栈有两个栈,一个保存正常数据stackData,一个保存正常数据中的较小值stackMin。在新数据压入栈时,比较其与stackMin中栈顶元素,如果新数据小于等于stackMin栈顶,则将其插入stackMin,否则舍弃。同样,在stackData出栈时,检查出栈元素和stackMin的栈顶元素是否相等,相等则stackMin也同样出栈,这样就保证了stackMin的顶部始终存储的是stackData中的最小元素。
如图压入3,4,5,1,2,1

代码如下
#include<iostream>
#include<assert.h>
#include<stack>
using namespace std;
template <class T>
class mystack
{
private:
stack<T> stackData;
stack<T> stackMin;
public:
void push(T newNum);
bool pop();
T getMin();
};
template<class T>
void mystack<T>::push(T newNum)
{
stackData.push(newNum);
if(stackMin.size() != 0)
{
if(stackMin.top() >= newNum)//在stackMin不为空时,新元素小于stackMin栈顶,则压入stackMin
stackMin.push(newNum);
}
else
stackMin.push(newNum);
return;
}
template<class T>
bool mystack<T>::pop()
{
if(stackData.size() == 0)
return false;
if(stackData.top() == stackMin.top())
{
stackData.pop();
stackMin.pop();
}
else
stackData.pop();
return true;
}
template<class T>
T mystack<T>::getMin()
{
assert(stackMin.size() != 0);
return stackMin.top();
}
int main()
{
mystack<int> ms;
for(int i=10; i>0; --i)
ms.push(i);
for(int i=0; i<10; ++i)
{
cout<<"mystack min = "<<ms.getMin()<<endl;
ms.pop();
}
return 0;
}
2.编写一个类,使用两个栈实现队列的基本功能poll,peek,add
(poll出队并返回队头元素,peek仅返回队头元素)
思路如下,设计两个栈,stackpush和stackpop,当要入队时,则向stackpush中压栈,当要出队时,将元素从stackpush弹出并压入stackpop中,这样从stackpop中弹出的即为队头元素。用图来说明

如图我们就可以清楚地看出来,如果要add元素时,队列中的元素应在stackpush中,当要poll或peek元素时,元素应该在stackpop中,所以,用一个flag来表明现在元素所在位置,0为队列为空,1表示元素在stackpush中,-1表示元素在stackpop中,这样每当要入队或出队时先查看当前元素所在位置,这样就知道是否需要将元素倒过来。
#include<iostream>
#include<assert.h>
#include<stack>
using namespace std;
template<class T>
class myqueue
{
private:
stack<T> stackpush;
stack<T> stackpop;
short flag;
public:
myqueue():flag(0){}
void add(T input);
T poll();
T peek();
};
template<class T>
void myqueue<T>::add(T input)
{
if(flag == -1)//元素在stackpop中,先把元素倒回stackpush
{
while(!stackpop.empty())
{
stackpush.push(stackpop.top());
stackpop.pop();
}
}
stackpush.push(input);
flag = 1;
return;
}
template<class T>
T myqueue<T>::poll()
{
if(stackpush.size()==0 &&stackpop.size()==0)
exit(1);
if(flag == 1)//元素在stackpush中,先把元素倒回stackpop
{
while(!stackpush.empty())
{
stackpop.push(stackpush.top());
stackpush.pop();
}
}
T res = stackpop.top();
stackpop.pop();
flag = -1;
return res;
}
template<class T>
T myqueue<T>::peek()
{
if(stackpush.size()==0 &&stackpop.size()==0)
exit(1);
if(flag == 1)
{
while(!stackpush.empty())
{
stackpop.push(stackpush.top());
stackpush.pop();
}
}
T res = stackpop.top();
flag = -1;
return res;
}
int main()
{
myqueue<int> mq;
for(int i=0; i<10; ++i)
mq.add(i);
for(int i=0; i<20; ++i)
{
if(i%2)
cout<<"poll = "<<mq.poll()<<endl;
else
cout<<"peek = "<<mq.peek()<<endl;
}
for(int i=0; i<10; ++i)
mq.add(i);
for(int i=0; i<20; ++i)
{
if(i%2)
cout<<"poll = "<<mq.poll()<<endl;
else
cout<<"peek = "<<mq.peek()<<endl;
}
return 0;
}
3.如何仅用递归操作来逆序一个栈
首先我们需要得到栈底元素并将其删除,然后再进行逆序即可
#include<iostream>
#include<stack>
using namespace std;
template<class T>
int getAndRemoveLastElement(stack<T> *st)
{
T res = st->top();
st->pop();
if(st->size() == 0)//递归循环,栈为空时说明到达栈底,返回栈底元素
return res;
else
{
T last = getAndRemoveLastElement(st);
st->push(res);
return last;
}
}
template<class T>
void reverse(stack<T> *st)
{
if(st->size() == 0)
return;
else
{
T i = getAndRemoveLastElement(st);//依次抽取栈底元素
reverse(st);//直到为空
st->push(i);//然后再进行压栈
}
}
int main()
{
stack<int> st;
for(int i=0; i<10; ++i)
st.push(i);
reverse(&st);
for(int i=0; i<10; ++i)
{
cout<<st.top()<<" ";
st.pop();
}
cout<<endl;
return 0;
}
不积小流无以成江河

浙公网安备 33010602011771号