快速求栈或队列中的最大值

来源:互联网 发布:c语言编程入门书籍 编辑:程序博客网 时间:2024/06/05 21:56

1.栈中最大值

       栈是按顺序压入,我们维护另外一个栈来记录栈当前的最大值。如果push值大于辅助栈的头元素,则辅助栈中压入要push的值,否则重复压入辅助栈的头元素。

       


       简单来说:push的时候两个栈都push,max栈push的时候要比较要push的元素和栈顶元素的大小,谁大push谁。代码参考如下。(这种情况下我们维护的max栈的大小和data栈的大小相同)

       

#include<iostream>#include<stack>using namespace std;template<typename T>class Cstack{private: stack<T>s; stack<T>maxs;public: void pushV(T& value);void popV();T& getPeek();T& getMax();};template<typename T>void Cstack::pushV(T &value){if(s.empty()){s.push(value);maxs.push(value);}else{s.push(value);int tmp=maxs.top();if(tmp>value)maxs.push(tmp);else maxs.push(value);}}template<typename T>void Cstack::popV(){if(s.empty())throw("empty stack!");s.pop();maxs.pop();}template<typename T>T & Cstack::getPeek(){if(s.empty())throw("empty stack!");return s.top();}template<typename T>T& Cstack::getMax(){if(s.empty())throw("empty stack!");return maxs.top();}

       当然有优化的地方,就是空间上maxs栈不用存储连续相同的最大值。也有看到用数组来类比栈的,另外一个数组来记录最大值的位置,基本上思想是一样的。


2.队列的最大值

       如果说栈增长的方向是单方向的,在push新元素时,只用更新新push元素所对应的最大值即可,因为之前压入不受后压入的元素的影响。影响只有:新压入元素受已压入元素的最大值的影响。已压入元素对应的最大值不受影响。

       队列不同,新压入元素的对应的最大值不受已压入元素的影响(因为他们会先pop),也就是他们仅和当前压入元素相关。复杂的是已压入的元素会受新压入 元素的影响。那么解决方案有两种。

       第一种,用multiset记录队列中的元素,push时insert集合,pop时删除相关值,求最大值时利用集合自动排序即可获得。

       第二种:先来看下两个栈实现一个队列。这时我先说这两个栈一个是数据栈,一个是输出栈。push、pop的操作文中写了,那么如何求最大值呢?

        数据栈和输出栈分别维护一个最大值栈,如栈中快速求取最大值的方法(1)。思路如下:

        


       两个队列实现一个栈的代码有了,只是在push的时候注意data1和max1捆绑,data2和max2捆绑。pop时也一样。求最大值时要在max1和max2中求最大的。

0 0
原创粉丝点击