利用模板实现Stack

说起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();

那么以下是我运行的结果:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ashley zhao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值