之前写过栈的,以为队列的也一样,结果一点都不一样。写了好久啊。
因为栈是后进先出,先进去的数字不会影响后面的数字;而队列是先进先出,后进去的会受先进入的数字的影响。
比如: (先) 1 9 3 8 4 (后) 这样的序列
栈存储 1 9 就可以了,因为9弹出后,自然 1 就是最大的
队列则不行,如果按上面存储9弹出后 剩下 3 8 4,8是最大的,没有存储。
我的方法,保存一个max的队列
入队列时: 如果新值比 max的最前面的元素大,那么把max清空,压入新值。 因为这个元素比所有值大,并且比所有值都晚弹出。
如果不满足上面条件,但是新值比数据队列的最后一个元素大或等于,把新值压入max队列。因为队列只剩下新值上一个元素和新值时,该新值就是最大的数字。
出队列时:如果弹出的数字和max队列最前面的数字一样大,弹出max中的元素
获得最大元素:获得max的最前面的元素。
#include <iostream> #include <queue> using namespace std; class My_Queue { public: My_Queue(){}; void EnQueue(int v) { if(max.empty()) { max.push(v); } else { if(v > max.front()) { while(!max.empty()) { max.pop(); } max.push(v); } else if(v >= data.back()) { max.push(v); } } data.push(v); } int DeQueue() { if(data.empty()) { printf("error"); return 0; } if(!max.empty() && data.front() == max.front()) { max.pop(); } int del = data.front(); data.pop(); return del; } int MaxElement() { if(max.empty()) { printf("no data "); return 0; } return max.front(); } queue<int> data; queue<int> max; }; int main() { My_Queue q; q.EnQueue(1); q.EnQueue(5); q.EnQueue(9); q.EnQueue(3); q.EnQueue(8); q.EnQueue(4); q.EnQueue(8); q.EnQueue(11); for(int i = 0; i < 8; i++) { printf("max:%d ", q.MaxElement()); printf("del:%d ", q.DeQueue()); } return 0; }
书上答案:
用两个栈A, B来构造队列,因为栈取最大可以O(1),利用栈使得队列取最大也是O(1)
数据入队列时:都压入栈B
数据出队列时: 若A为空,则把B的数据依次弹出给A,再弹出A的最后一个元素 (两次后进先出就变成了先进先出)
若A不空,直接弹出A的最后一个元素
取最大值: 取栈A 和 栈B 最大值里 更大的那一个