使用C++动态数组实现基本数据结构--栈

数据结构虽然经常在用,但是时间久了,很多东西都比较零散,最近有空就重新梳理一遍数据结构相关的知识,顺便用C++挨个实现一下,一则强化自己的记忆,二则为初学者一些编程指引。虽然基本的数据结构在C++的STL(标准模版库)中大多都有实现,但是自己实现一遍的效果远大于拿现成的来用。

打算把基本的数据结构逐个实现一遍,使用C++模版编程,代码中有不当之处,还请各位大牛不吝赐教,我会积极学习并改正。大家一起来见证!

直接上源码:

#ifndef MYSTACK_H_
#define MYSTACK_H_

/*******************************************************************
文件名:MyStack.h
作   者:吾理小子
版   本:v1.0
日   期:2020-03-15
功   能:使用C++模版类实现栈的基本功能
********************************************************************/
#include
#include


#define  DEFAULT_SIZE  10   //堆栈默认大小

/*定义堆栈块,用结构体定义方便扩展使用*/
template 
struct StackBlock
{
    T data;
};

template 
class MyStack
{
    public:
        MyStack();
        MyStack(int size);     //重载构造函数,设定栈容量
        ~MyStack();
        inline void push(T const& dat);  
        inline void pop();
        inline int  size() const;
        inline bool empty() const;        
        T&   top() const;      //取栈顶元素
        void show() const;     //调试使用,显示堆栈内容

    private:
        inline bool full() const;    //判断堆栈是否已满
        void expand();               //用于堆栈扩容
           
    private:
        StackBlock *top_   = nullptr;  //栈顶指针
        StackBlock *stack_ = nullptr;  //栈数据
        int        capacity_;             //堆栈容量
};

template 
MyStack::MyStack()
     
{
    capacity_ = DEFAULT_SIZE;  //用默认大小申请栈空间
    if(stack_ == nullptr)
    {                          //申请容量+1,栈顶指针指向此
        stack_ = new StackBlock [capacity_ + 1];
    }

    top_ = stack_;
}

template 
MyStack::MyStack(int size) : capacity_(size)  //频繁入栈时,用此构造函数,效率高
{
    if(stack_ == nullptr)
    {
        stack_ = new StackBlock [capacity_ + 1];
    }

    top_ = stack_;
}

template 
inline void MyStack::push(T const& dat)
{
    if (full())  //栈已满,需要扩容
    {
        expand();
    }

    top_->data = dat;
    ++top_;
}

template 
inline void MyStack::pop()
{
    if (empty())  //栈空时,直接退出
    {
        return;
    }

    --top_;
}

template 
inline int MyStack::size() const
{
    return capacity_;
}

template 
inline bool MyStack::empty() const
{
    return (top_ == stack_);
}

template 
inline bool MyStack::full() const
{
    return (top_ == &stack_[capacity_]);
}

template 
void MyStack::expand()       //扩容函数
{
    std::cout << "expand capacity!" < *tmp = new StackBlock[new_capacity + 1];  //申请新空间
    if (tmp == NULL)  //申请空间不成功,抛出异常
    {
        throw "apply memery failed!";
    }
    
    /*申请新空间成功,拷贝原有堆栈元素,释放原有堆栈,更改栈顶指针指向,修改新容量值*/
    memcpy(tmp, stack_, sizeof(StackBlock) * capacity_);
    delete []stack_;
    stack_ = tmp;
    top_ = &stack_[capacity_];
    capacity_ = new_capacity;
}

template 
T& MyStack::top() const
{
    if (empty())  //堆栈为空时,取栈顶元素时抛出异常
        throw "stack is empty!";
    else
        return (top_ - 1)->data;
}

template 
void MyStack::show() const
{
    if(empty())
        return;
        
    StackBlock *tmp = top_ - 1;

    std::cout << "\n  <--top" << std::endl;
    while (tmp >= stack_)
    {
        std::cout << tmp->data << std::endl;
        --tmp;
    }
    std::cout << std::endl;
}

template 
MyStack::~MyStack()
{
    if(stack_ != nullptr)
        delete [] stack_;  //释放申请的空间
}


#endif

在h文件中实现了全部内容,重点的位置都进行了注释,有不理解的地方,欢迎与吾理小子交流学习。

使用时包含该头文件,创建一个对象后即可使用。测试工程在VS2017下编译后上传,有需要的朋友下载参考。

测试工程:

 

 

你可能感兴趣的:(数据结构与算法)