#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;
}