栈结构是学习数据结构到现在为止写起来最短的,但是也是我使用到现在为止,最不会应用的,到底什么场景下面应该使用栈结构来达到省时省力还是不能做出很好的决定。这应该也是源于对栈结构在现实场景中理解不够的原因吧
后面还会有链表描述方法的栈结构实现
#ifndef _H_MYSTACK_ARRAY_H
#define _H_MYSTACK_ARRAY_H
/宏定义栈的临界长度,超过此长度之后需要在利用率较低的情况下回收空间
#define BOUNDARY_LENGTH 2048
#include <iostream>
template<class T>
class myStack_array;
template<class T>
class myStack_array
{
public:
myStack_array(int initLength = 128);
myStack_array(const myStack_array<int>& st);
~myStack_array();
void push(const T val);/元素压栈,如果栈满(1、可以抛出异常;2、可以申请更大空间)
T pop(void);/弹出栈顶元素(删除栈顶元素,如果不存在,则throw异常)
int clear(void);清空,并且返回元素数目
T top(void);///仅仅返回栈顶元素,为空则抛出异常
int size(void);/计算元素的数目
bool isEmpty(void);///指示栈是否为空
bool isFull(void);/只是栈是否为满
void operator=(const myStack_array<int>& st);
private:
T* m_pHead;
int m_len;
int m_pos;
};
template<class T>
myStack_array<T>::myStack_array(int initLength)
{
m_len = initLength;
m_pHead = new T[m_len];
memset(m_pHead, 0, m_len);
m_pos = -1;
}
template<class T>
myStack_array<T>::myStack_array(const myStack_array<int>& st)
{
m_len = st.m_len;
m_pHead = new T[m_len];
m_pos = st.m_pos;
memcpy(m_pHead,st.m_pHead, m_len * sizeof(T));
}
template<class T>
myStack_array<T>::~myStack_array()
{
delete[] m_pHead;
}
template<class T>
void myStack_array<T>::push(const T val)/元素压栈,如果栈满(1、可以抛出异常;2、可以申请更大空间)
{
if(m_pos >= (m_len - 1))如果满了就新申请空间,并且全部搬过去
{
T* newHead = new T[1 + m_len * 1.2];
memcpy(newHead, m_pHead, sizeof(T) * m_len);
m_len = 1 + m_len * 1.2;///为了保证必然会多一个空间出来(在原来空间比较小的情况下,可能1.2倍取整不好使)
delete[] m_pHead;
m_pHead = newHead;
std::cout<<std::endl<<"StackExpanded"<<std::endl;
}
m_pos = m_pos + 1;
m_pHead[m_pos] = val;
}
template<class T>
T myStack_array<T>::pop(void)/弹出栈顶元素(删除栈顶元素,如果不存在,则throw异常)
{
if(m_pos < 0)
{
throw("NoElmentInStack");
}
if(m_len > BOUNDARY_LENGTH)
{
float usage = float(m_pos + 1) / float(m_len);
if(usage < 0.3)
{
T* newHead = new T[m_len / 2];
m_len = m_len / 2;
memcpy(newHead, m_pHead, m_len * sizeof(T));
delete[] m_pHead;
m_pHead = newHead;
}
}
m_pos = m_pos - 1;
return(m_pHead[m_pos + 1]);
}
template<class T>
int myStack_array<T>::clear(void)清空,并且返回元素数目
{
memset(m_pHead, 0, m_len);
m_pos = -1;
}
template<class T>
T myStack_array<T>::top(void)///仅仅返回栈顶元素,为空则抛出异常
{
if(m_pos < 0)
{
throw("NoElmentInStack");
}
return(m_pHead[m_pos]);
}
template<class T>
int myStack_array<T>::size(void)/计算元素的数目
{
return(m_pos + 1);
}
template<class T>
bool myStack_array<T>::isEmpty(void)///指示栈是否为空
{
return(-1 == m_pos);
}
template<class T>
bool myStack_array<T>::isFull(void)
{
return(m_pos == (m_len -1));
}
#endif
下面是测试使用的,应该没有问题吧
#include "myStack_array.cpp"
#include <iostream>
void main(void)
{
myStack_array<int> mst(1);
int topVal = 0;
for(int ii = 0; ii < 10; ii++)
{
topVal = ii * ii;
std::cout<<"isFull : "<<mst.isFull()<<std::endl;
mst.push(topVal);
std::cout<<topVal<<"\t";
}
std::cout<<std::endl;
std::cout<<mst.size()<<std::endl;
try
{
for(int ii = 0; ii < 4; ii++)
{
topVal = mst.top();
std::cout<<topVal<<"\t";
}
std::cout<<std::endl;
}
catch(char* ex)
{
std::cout<<ex<<std::endl;
}
while(!mst.isEmpty())
{
topVal = mst.pop();
std::cout<<topVal<<"\t";
}
std::cout<<std::endl;
try
{
for(int ii = 0; ii < 4; ii++)
{
topVal = mst.top();
std::cout<<topVal<<"\t";
}
std::cout<<std::endl;
}
catch(char* ex)
{
std::cout<<ex<<std::endl;
}
std::system("pause");
}