一.设计思路
我个人的理解中stack是一个先进后出的一个容器,那么对与这个容器的对应数据结构肯定就是顺序表比较好,因为顺序表更加适合尾部的删除和插入,它的时间更加短,并且由于要知道头部的索引,所以肯定要管理一个top的索引,并且对于一个stack中,我们也要知道这个容器所占有的空间,所以说也需要维护一个size的大小,这便是具体的思路,如果用链表来进行管理,其实大致也是一样的思路。
template<typename T>
class mystack
{
private:
T* data;
int top;
int size;
}
二.函数实现
对于这个stack中,我们都知道肯定需要基本的pop和push,然后就是查看栈顶端元素的函数,然后就是一些基础的函数,其实实现起来都比较简单,这里就是单纯的讲解一下基础的pop和push函数,对于pop函数,我们知道是一个将栈顶元素弹出,这个时候第一步肯定就是判断栈是不是为空,如果是空,那么弹出就没有什么意义,这个时候我们可以定义一个宏,然后将这个宏弹出,如果不是为空,我们就将data【top】这个元素进行弹出,但是这个top却没有减少,所以说我们可以这个写弹出data【top--】,这样栈顶元素也就进行了减一
而对于push函数来说,就是向栈顶插入一个元素,对于这个函数来说,第一步肯定是判断栈是否已满,如果满了(sizeof(T)*top == size),则就开始扩容,我一般实现扩容都是采用realloc,所以对应的,我在最开始构造函数申请空间的时候就会使用malloc,一般我都是扩容sizeof(T)*(top+10),这样可能会存在空间浪费的问题,但是能减少内存申请的次数,后面就是将对应的top加一然后将data【top】=val就结束了这次空间申请。
三.构造函数和析构函数的实现
对于构造函数来说,如果是没有参数的,那么我会使用malloc来开辟一个四个单位的空间,然后再赋值对应的top和size,如果是传入的是一个数组,然后就开辟对应的空间,然后将每个值进行深度拷贝,然后赋值对应的top和size
对应析构函数来说,就是将对应的data进行free,将内存释放,就结束了这个stack的寿命
mystack()
{
data = (T*)malloc(sizeof(T) * 4);
top = 0;
size = sizeof(T) * 4;
}
mystack(T* an)
{
int n = sizeof(an) / sizeof(T);
for (int i = 0; i < n; i++)
{
data[i] = an[i];
}
top = n - 1;
size = sizeof(an);
}
~mystack()
{
free(data);
}