记得当初学习数据结构,所有的数据结构均是C语言实现,除了数组最简单的数据结构非堆栈(通常所说的堆栈指栈,其实栈和堆还是有些区别)莫属,现在用C++封装Stack类,模拟栈操作。
1.首先是头文件的声明,文件名为"Stack.h",代码如下:
#define STACK_H
template <class T>
class Stack
{
private:
T *m_Data;
int m_buffSize;//栈的大小
int m_nCount;//栈中元素个数
const int m_onceAlloc;//一次分配的最大元素个数,这里一次性分配不止一个T类型空间,减少每次插入元素时都进行内存空间重定向和内容拷贝
public:
//构造函数
Stack(int buffSize = 0);
//析构函数
~Stack();
//销毁栈
bool DestroyStack();
//清空栈中元素
bool Clear();
//判断栈是否为空
bool isEmpty();
//求栈的长度,返回栈中元素个数
int GetLength();
//获取栈顶元素
const T GetTop();
//入栈
bool Push(const T &elem);
//将栈顶元素出栈
bool Pop();
};
#endif
2.然后是实现文件,文件名为"Stack.cpp",代码如下
using namespace std;
template <class T>
Stack<T>::Stack(int buffSize = 0)
:m_buffSize(buffSize)
,m_onceAlloc(10)
,m_nCount(0)
,m_data(NULL)
{
if(0 > m_buffSize)
{
cout << "Application for space allocation(the stack space is above zero) is invalid:buffSize = " << m_buffSize
<< ",now we use default constructor" << endl;
m_buffSize = 0;
}
else
{
m_data = new T[buffSize];
}
//析构函数
template <class T>
Stack<T>::~Stack()
{
if (m_Data != NULL)
{
delete[] m_Data;
m_Data = NULL;
}
}
//销毁栈
template <class T>
bool Stack<T>::DestroyStack()
{
delete this;
return TRUE;
}
//清空栈中元素
template <class T>
bool Stack<T>::Empty()
{
if (m_Data != NULL)
{
delete[] m_Data;
m_Data = NULL;
m_buffSize = 0;
m_nCount = 0;
}
cout << "The stack is already empty !" << endl;
}
//判断栈是否为空
template <class T>
bool Stack<T>::isEmpty()
{
return 0 == m_nCount;
}
//获取栈的长度
template <class T>
int Stack<T>::GetLength()
{
return m_nCount;
}
//获取栈顶元素
template <class T>
const T Stack<T>::GetTop()
{
return m_Data[m_nCount - 1];
}
//入栈
template <class T>
bool Stack<T>::Push(const T &elem)
{
//如果存储元素个数小于栈的大小
if (m_nCount < m_buffSize)
{
m_Data[m_nCount++] = elem;
}
else
{
//重新分配存储空间
T *m_TempData = new T[m_buffSize + m_onceAlloc];
//将原空间存储内容拷贝到新空间
memcpy(m_TempData,m_Data,m_nCount*sizeof(T));
m_buffSize = m_nCount + m_onceAlloc;
m_TempData[m_nCount++] = elem;
//释放原空间
delete[] m_Data;
m_Data = m_TempData;
}
return TRUE;
}
//将栈顶元素出栈
template <class T>
bool Stack<T>::Pop()
{
//如果弹出元素后和上一次分配之前栈的大小相同
if (--m_nCount == m_buffSize - m_onceAlloc)
{
m_buffSize -= m_onceAlloc;
T *tempData = new T[m_buffSize];
memcpy(tempData,m_Data,m_buffSize*sizeof(T));
delete[] m_Data;
m_Data = tempData;
}
//如果出栈元素个数小于一次性最大分配单元数时
else
{
m_Data[m_nCount+1] = 0;
}
}
为简单起见,没有引入C++异常机制,如若有什么错误和疏忽遗漏的地方,欢迎大家指正。