看到这个题目,大概会想到三种方法实现:
(1)用奇数位下标存放一个栈的内容,用偶数位下标存放另外一个栈的内容。
(2)从数组的中间一分为二,左边是一个栈,右边是一个栈,分别向两边延伸,栈底都是中间,栈顶向两边。
(3)数组的两边分别做两个栈的栈底,两个栈向中间生长。
简单的分析后,我们知道其他两种方法在运用的过程中总会产生更多的空间浪费,所以我们认为第三种方法是最好的,下面我们给出第三种方法的实现:
代码如下:
#include <iostream>
using namespace std;
template <class T>
class StackArr
{
public:
StackArr()
:_Array(new int[2])
,_Stack1(0)
,_Stack2(1)
,_Capacity(2)
{}
~StackArr()
{
if (_Array)
{
delete[] _Array;
_Stack1 = 0;
_stack2 = 0;
_Capacity = 0;
}
}
void PushStack1(const T& data)
{
Capacity();
_Array[_Stack1] = data;
_Stack1++;
}
void PushStack2(const T& data)
{
Capacity();
_Array[_Stack2] = data;
_Stack2--;
}
void PopStack1()
{
if (_stack1 > 0)
_Stack1--;
}
void PopStack2()
{
if (_stack2 < _Capacity)
_Stack2++;
}
T& TopStack1()
{
if (_Stack1 > 0)
return _Array[stack1 - 1];
return NULL;
}
T& TopStack2()
{
if (_Stack2 > 0)
return _Array[stack2 + 1];
return NULL;
}
int SizeStack1()
{
return _Stack1;
}
int SizeStack2()
{
return (_Capacity - 1 - _Stack2);
}
bool EmptyStack1()
{
if (_Stack1 != 0)
return false;
return true;
}
bool EmptyStack2()
{
if (_Stack2 != _Capacity - 1)
return false;
return true;
}
private:
//此处内存扩充函数(重要)
void Capacity()
{
if (SizeStack1() + SizeStack2() >= _Capacity)
{
int _NewCapacity = _Capacity * 2;
T* temp = new _NewArray[_NewCapacity];
int k = _NewCapacity - 1;
for (size_t i = 0; i < _Stack1; ++i)
temp[i] = _Array[i];
for (size_t j = _Capacity - 1; j > _Capacity - _Stack2; --j)
{
temp[j] = _Array[j];
k--;
}
delete[] _Array;
_Capacity = _NewCapacity;
_Stack2 = k;
_Array = temp;
}
}
T* _Array;
int _Stack1;
int _Stack2;
int _Capacity
};
注意:
1、_Stack1与_Stack2分别指向栈顶元素下一个位置。
2、拷贝时候String类型。