栈操作


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



猜你喜欢

转载自blog.csdn.net/mayi_xiaochaun/article/details/49250741