说起stack,可能很多人都写过,但是这是我第一次写,而且出错率特别高;
那么首先看看什么是Stack;
栈Stack是一个“先进后出”的容器;
a、栈是只能在某一端插入和删除的特殊线性表。
b、先堆进来的压在底下,随后一个一个往上堆。取走时,只能从上面一个一个取。读和取都在顶部进行,底部一般是不动的。
c、栈就是一种类似桶堆积物品的数据结构,进行删除和插入的一端称栈顶,另一端称栈底。插入一般称为进栈,删除则称为退栈。 栈也称为后进先出表。
以下是我对于此次代码的分析和总结;
1).h文件
定义模板类:
template<class T>
class Stack{};
定义类的私有的成员变量:
T* _pData;//指向栈顶
size_t _size; //找当前的大小
size_t _capacity; // 栈总的大小
对于stack,我们要完成它以下的几个功能:
Stack();
Stack(const Stack<T>& s);
Stack<T>& operator=(const Stack<T>& s);
void Push(const T& data);
void Pop();
bool Empty()const;
T& Top();
size_t Size()const;
~Stack();
上面这些功能都很好实现,但是你对于其中有一个功能的实现让我很头疼,这就是CheckCapacity():
void CheckCapacity() //检查内存是否分配够,不够时扩展内存
{
if(_size>=_capacity)
{
T *pcur =_pData;
size_t NewCapacity=2*_capacity+3;//申请新空间
_pData = new T[NewCapacity];
for(size_t idx = 0; idx < _size; idx++)
{
_pData[idx] = pcur[idx];
}
delete[] pcur; //删除旧空间
_capacity = NewCapacity;
//_pData=_pData+_size;//这句话的出现和构造函数的不要重复
}
}
以下是构造函数的实现:
//初始化列表时不要把 _pData(pData)写成_pData=pData
Stack(size_t size)
:_pData(NULL)
,_size(size)
,_capacity(10)
{
if(size>=0)
{
_pData = new T[_capacity];
}
}
析构函数的实现:
~Stack() //析构函数
{
if(_pData!=NULL)
{
delete _pData;
_pData=NULL;
_size=0;
}
}
拷贝构造函数:
Stack(const Stack<T>& s) //拷贝构造函数
{
if(_pData!=NULL)
{
_pData=s._pData;
_size=s._size;
_capacity=s._capacity;
}
}
赋值运算符重载的实现:
Stack<T>& operator=(const Stack<T>& s) //赋值运算符重载
{
if(this!=&s)
{
_pData=s._pData;
_size=s._size;
_capacity=s._capacity;
}
return *this;
}
进栈:
void Push(const T& data)
{
CheckCapacity();
_pData[_size++]=data;
}
出栈:
void Pop() //出栈
{
_size--;
}
访问栈顶:
T& Top( ) //访问栈顶
{
return *_pData;
}
判空:
bool Empty()const //判空
{
if(_size==0)
return true;
return false;
}
栈中实际元素个数:
size_t Size()const //栈得到大小
{
return _size;
}
和栈实际分配内存空间:
size_t Capacity()
{
return _capacity;
}
销毁栈:
bool DestroyStack()
{
delete this;
return true;
}
返回栈中的元素:
T& get()
{
return *_pData;
}
打印栈中的所有元素:
void print()//输出
{
for (int idx = _pData[_size]; idx > 0; --idx)
{
cout << _pData[idx-1] << " ";
}
cout << endl;
}
2).cpp文件
为什么我要发测试代码,就是有时候可能会在类外使用对象调用类的室友成员变量:
s是我定义的一个对象
s. _pData;//指向栈顶
s. _size; //找当前的大小
s. _capacity; // 栈总的大小
向这样的写法是完全错误的,在测试代码中调用类的私有成员是不被允许的,所以最好在类中定义函数在获取他们 T& get()和getsize()等。
以下是我的测试代码:
int size=0;
Stack<int> s(size);
s.Push(1);
s.Push(2);
s.Push(3);
s.Push(4);
s.Push(5);
s.Push(6);
s.Push(7);
s.Push(8);
s.Size();
s.Pop();
s.print();
s.Top();
Stack<int> s1(size);
s1=s;
cout<<s1.Size()<<""<<endl;
s1.print();
s1.Pop();
cout<<s1.Size()<<""<<endl;
s1.print();
Stack<int> s2(s);
cout<<s2.Size()<<""<<endl;
s2.print();
那么以下是我运行的结果: