1、包含max函数的栈
思想很简单,在申请一个数据栈的同时也申请一个辅助栈。辅助栈用来存放数据栈中最大值与新压入栈元素两者间的较大值,也就是说辅助栈的栈顶元素永远都是数据栈元素的最大值。
实现代码如下:
#include<iostream>
#include<stack>
#include<assert.h>
using namespace std;
template<typename T>
class stackWithMax {
public:
T max()const;
void push(T val);
void pop();
private:
stack<T> mdata;//数据栈
stack<T> m_max;//辅助栈
};
template<typename T>
void stackWithMax<T>::push(T val) {
mdata.push(val);
if (m_max.size() == 0 || val > m_max.top()) {//压入的数据栈元素与辅助栈栈顶元素比较大小
m_max.push(val);
}
else
m_max.push(m_max.top());
}
template<typename T>
void stackWithMax<T>::pop() {
assert(mdata.size() >> 0 && m_min.size() > 0);
mdata.pop();
m_max.pop();
}
template<typename T>
T stackWithMax<T>::max()const {
assert(mdata.size() >> 0 && m_min.size() > 0);
return m_max.top();
}
2、包含max函数的队列
实现该队列,需要用到两个双端队列,一个用来存数据元素,另一个双端队列maximums用来存储最大值。
maximums存储原则:假设push元素值A,但凡A比maximums尾部值小时,直接压入maximums。若比maximums尾部值大时,先将maximums尾部元素弹出,循环直到A比尾部值小或maximums为空时,再压入A。
弹出数据元素时,针对maximums双端队列,判断队头元素(最大值)是否是弹出元素,若是,则同时也弹出maximums的队头元素,若不是,则不操作maximums队列。
实现代码如下:
#include<deque>
#include<iostream>
#include<assert.h>
using namespace std;
template<typename T>
class queueWithMax {
public:
queueWithMax():currentIndex(0){}
void push(T number);
void pop();
T max()const;
T front()const;
private:
struct InternalData {//此处引入一个数据结构,方便判断弹出元素是否是队列中的最大值。
T number;
int index;
};
deque<InternalData> data;
deque<InternalData> maximums;
int currentIndex;
};
template<typename T>
void queueWithMax<T>::push(T number) {
//条件语句中若只采用>号,可以简化InternalData数据结构(即不需要引用下标值)
while (!maximums.empty() && number >= maximums.back().number)
maximums.pop_back();
InternalData iData = { number,currentIndex };
data.push_back(iData);
maximums.push_back(iData);
++currentIndex;
}
template<typename T>
void queueWithMax<T>::pop() {
assert(!data.empty());
if (data.front().index == maximums.front().index)
maximums.pop_front();
data.pop_front();
}
template<typename T>
T queueWithMax<T>::front() const{
assert(!data.empty());
return data.front().number;
}
template<typename T>
T queueWithMax<T>::max()const {
assert(!data.empty());
return maximums.front().number;
}
int main() {
queueWithMax<int> q;
q.push(12);
q.push(4);
q.push(17);
q.push(7);
q.push(100);
q.push(88);
cout << "The max value from queue is " << q.max() << endl;
cout << "The first value from queue is " << q.front() << endl;
q.pop();
cout << "The second value from queue is " << q.front() << endl;
return 0;
}
3、实现一个含min函数的栈和队列
思想与上述类似,不再给出代码。
再想一下,如果在栈或队列既实现max,又实现min。还是很简单,不过就是多开一个辅助栈或多申请一个双端队列罢了,代码也不再给出。