1,栈
1.1,用数组实现栈
template <typename T>
class Stack{
private:
int stk_top;
int max_top;
T* stk;
public:
Stack(int max = 100);
~Stack(){delete [] stk};
bool empty()const{return stk_top == -1;}
bool full()const{return stk_top == max_top;}
int size()const{return stk_top+1;}
T top()const;
Stack<T>& push(const T& x);
Stack<T>& pop(T& x)
}
template <typename T>
Stack<T>::Stack(int max)
{
stk = new T[max];
stk_top = -1;
max_top = max-1;
}
template <typename T>
T Stack<T>::top()const
{
if(!empty())
return stk[stk_top];
}
Stack<T>& Stack<T>::push(const T& x)
{
stk[++stk_top]=x;
return *this;
}
Stack<T>& Stack<T>::pop(T& x)
{
x = stk[stk_top--];
return * this;
}
1.2 设计包含min函数的栈
问题:定义栈的数据结构,要求添加一个min 函数,能够得到栈的最小元素。 要求函数min、push 以及pop 的时间复杂度都是O(1)。
思路1:需要一个辅助栈。每次push一个新元素的时候,同时将最小元素(或最小元素的位置。考虑到栈元素的类型可能是复杂的数据结构,用最小元素的位置将能减少空间消耗)push到辅助栈中;每次pop一个元素出栈的时候,同时pop辅助栈。
思路2:特别的,针对思路1,可以将辅助栈进行压缩,仅仅当下一个最小值<=辅助栈栈顶元素时,才入辅助栈。
template<typename T>
class StackSuppliedMin{
public:
vector<T> datas;
vector<size_t> minStack;
void push(T data){
datas.push_back(data);
if (minStack.empty() || data <= datas[minStack.back()])//<=说明了允许有重复元素
minStack.push_back(datas.size()-1);
}
void pop(){
assert(!datas.empty());
if (datas.back() == datas[minStack.back()])
minStack.pop_back();
datas.pop_back();
}
T min(){
assert(!datas.empty() && !minStack.empty());
return datas[minStack.back()];
}
void display();
};
1.3 栈的push、pop 序列
题目:输入两个整数序列。其中一个序列表示栈的push顺序,判断另一个序列有没有可能是对应的pop 顺序。
例如:以下是不合法的一种顺序。
push数组 | 1 | 2 | 3 | 4 | 5 |
pop数组 | 4 | 5 | 3 | 1 | 2 |
数组下标 | 0 | 1 | 2 | 3 | 4 |
判断方法即模拟人工的检验方法,真的造出一个栈来试验这种情况。用i1来遍历push数组,用i2来遍历pop数组,注意i1一定可以到达n,而i2不能到达n时说明不合法。
bool isPopSeries(int push[], int pop[], int n) {
//指针遍历push
int i1=0;
//指针遍历pop
int i2=0;
stack<int> intStack;
while(i2<n){//i1肯定能走到n,而i2不一定能走到n
while(intStack.empty()||intStack.top()!=pop[i2]){
if(i1<n)
intStack.push(push[i1++]);
else//i1==n即i1走完了,但是却无法pop
return false;
}
while(!intStack.empty()&&intStack.top()==pop[i2]){
intStack.pop();
i2++;
}
}
return true;
}
2.2 用数组实现队列