栈是一种特殊的线性表,
线性表是具有相同类型的n(n>=0)个数据元素的有序(中间不能空位置)有限序列。
对栈的操作(增/删/读)只能通过栈的一端进行,允许操作的一端称之为栈顶,不允许操作的一端称为栈底。栈的特性为先进后出。c++实现栈,可采用如下的设计思路:
Stack是一个接口类,封装了栈的所有操作:
//Stack.h
#ifndef __STACK_H__
#define __STACK_H__
#include <exception>
template<typename T>
class Stack
{
public:
virtual void push(const T& e) = 0; //入栈
virtual void pop() = 0; //出栈
virtual T top() const = 0; //读栈顶元素
virtual void clear() = 0; //清空栈
virtual int size() const = 0; //获取栈元素的个数
};
#endif
数组实现的栈空间:
//StaticStack.h
#ifndef __STATICSTACK_H__
#define __STATICSTACK_H__
#include "Stack.h"
template <typename T, int N>
class StaticStack : public Stack<T>
{
protected:
T m_space[N];
int m_top; //标志栈顶元素所在下标
int m_size; //标志栈空间中有多少个元素
public:
StaticStack()
{
m_top = -1;
m_size = 0;
}
int capacity() const
{
return N;
}
void push(const T& e)
{
if (m_size < N)
{
m_space[m_top + 1] = e;
++m_top;
++m_size;
}
else
throw(std::out_of_range("StaticStack::push() out of randge"));
}
void pop()
{
if (m_size > 0)
{
--m_top;
--m_size;
}
else
throw(std::runtime_error("No element in current stack"));
}
T top() const
{
if (!(m_size > 0))
{
std::runtime_error("No element in current stack");
}
return m_space[m_top];
}
void clear()
{
m_top = -1;
m_size = 0;
}
int size() const
{
return m_size;
}
};
#endif /* __STATICSTACK_H__ */
用户要使用StaticStack生成栈数据结构时,需要指定通过泛型参数N传入数组的大小:
//main.cpp
int main()
{
for (int i = 0; i < 5; ++i)
{
stack.push(i);
}
while (stack.size() > 0)
{
std::cout << stack.top() << std::endl;
stack.pop();
}
getchar();
return 0;
}
StaticStack存在的缺陷是如果存储的元素为类类型,那么在创建StaticStack的对象时将会多次调用元素类型的构造函数,显然,这十分影响效率,甚至多做一些无用功。改进方法可以是用单向链表来生成栈空间:
//LinkStack.h
#ifndef __LINKSTACK_H__
#define __LINKSTACK_H__
#include "LinkStack.h"
#include "LinkList.h"
template<typename T>
class LinkStack : public Stack<T>
{
protected:
LinkList<T> m_list;
public:
void push(const T& e)
{
m_list.insert(0, e);
}
void pop()
{
if (m_list.length() > 0)
{
m_list.remove(0);
}
else
throw(std::runtime_error("No element in current stack"));
}
T top() const
{
if (m_list.length() > 0)
return m_list.get(0);
else
throw(std::runtime_error("No element in current stack"));
}
void clear()
{
m_list.clear();
}
int size() const
{
return m_list.length();
}
};
#endif /* __LINKSTACK_H__ */