#pragma once #include <iostream> #include <stack> using namespace std; template<class T> class MyStack { public: MyStack(); ~MyStack(); /* 题目21 :定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。 要求函数min、push以及pop的时间复杂度都是O(1)。 */ void push(const T& value); void pop(); const T& min(); /* 题目22 : 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。 假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是 该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。 */ /* 思路:如果下一个弹出的数字刚好是栈顶数字,那么直接弹出. 如果下一个弹出的数字不是栈顶数字,那么将压栈序列中还没有入栈的数字压入辅助栈,直到把下一个需要弹出的数字压入栈顶为止. 如果所有的数字都压入栈中,且仍然没有找到下一个弹出的数字,那么该序列不是一个弹出序列*/ bool IsPopOrder(const int* pPush, const int* pPop, int length); private: stack<T> dataStack; //用于存储入栈值的数据栈 stack<T> minStack; //用作存储最小值的辅助栈 };
#include "MyStack.h" template<class T> MyStack<T>::MyStack() { } template<class T> MyStack<T>::~MyStack() { } //压栈,使用复制粘贴minStack保存最小值,并让最小值一直处在栈顶 //如果辅助栈为空,则直接入栈 //如果当前元素小于辅助栈的栈顶元素,则压入辅助栈顶 //如果当前元素大于等于辅助栈的栈顶元素,则再次将辅助栈顶元素压入辅助栈顶 template<class T> void MyStack<T>::push(const T& value) { dataStack.push(value); if (minStack.empty() || value < minStack.top()) { minStack.push(value); } else { minStack.push(minStack.top()); } } //出栈 template<class T> void MyStack<T>::pop() { if (!dataStack.empty() && !minStack.empty()) { dataStack.pop(); minStack.pop(); } } //最小值 template<class T> const T& MyStack<T>::min() { if (!dataStack.empty() && !minStack.empty()) { return minStack.top(); } } /* 思路:如果下一个弹出的数字刚好是栈顶数字,那么直接弹出. 如果下一个弹出的数字不是栈顶数字,那么将压栈序列中还没有入栈的数字压入辅助栈,直到把下一个需要弹出的数字压入栈顶为止. 如果所有的数字都压入栈中,且仍然没有找到下一个弹出的数字,那么该序列不是一个弹出序列*/ template<class T> bool MyStack<T>::IsPopOrder(const int* pPush, const int* pPop, int length) { bool bPossible = false; if (pPush != NULL && pPop != NULL && length > 0) { const int *pNextPush = pPush; const int *pNextPop = pPop; stack<int> dataStack; //当出栈序列不为NULL,继续执行 while (pNextPop - pPop < length) { //如果下一个弹出的数字不是栈顶数字,那么将压栈序列中还没有入栈的数字压入栈, //直到把下一个需要弹出的数字压入栈顶为止. while (dataStack.empty() || (dataStack.top() != *pNextPop)) { //压栈序列已经全部压入栈中,跳去循环 if (pNextPush - pPush == length) { break; } dataStack.push(*pNextPush); pNextPush++; } //如果所有的数字都压入栈中,且仍然没有找到下一个弹出的数字,那么该序列不是一个弹出序列 if (dataStack.top() != *pNextPop) { break; } //找到 dataStack.pop(); pNextPop++; } if (dataStack.empty() && (pNextPop - pPop == length)) { bPossible = true; } } return bPossible; }
#include "MyStack.cpp" int main(void) { MyStack<int> MS; //包含min函数的栈 MS.push(3); MS.push(4); MS.push(2); cout << MS.min() << endl; MS.pop(); cout << MS.min() << endl; //栈的压入和弹出序列 int pPush[] = { 1, 2, 3, 4, 5 }; //压入序列 int pPop[] = { 4, 3, 5, 1, 2}; //弹出序列 cout << "bool:"<<MS.IsPopOrder(pPush, pPop, 5) << endl; return 0; }