把线性表的插入和删除操作限制在同一端进行就得到栈数据结构,因此栈是一个后进先出(LIFO)的数据结构。
抽象数据类型ADT
#pragma once
template <typename T>
class stackADT{
public:
virtual ~stackADT(){
}//虚析构函数
virtual bool empty() const = 0;//栈空返回true
virtual int get_size() const = 0;//返回栈里元素个数
virtual T top() const = 0;//返回栈顶元素
virtual void push(const T& _element) = 0;//压栈
virtual void pop() = 0;//出栈
};
栈操作的异常类
#pragma once
#include <string>
using std::string;
#include <iostream>
using std::cin; using std::cout; using std::cerr; using std::ostream; using std::istream;
using std::ends; using std::endl;
class stackEmpty{
public:
stackEmpty(string _message="Invalid operation on empty stack!"):message(_message){
}
~stackEmpty(){
}
string what()const {
return message; }
void output()const {
cerr << message << endl; }
private:
string message;
};
基于线性表–数组描述的栈实现
#pragma once
#include "stackEmpty.h"
#include "stackADT.h"
#include "../../../ch05/ArrayList/ArrayList/myArrayList.h"
//=========================从数组表myArrayList派生得到的数组栈类==============================
template <typename T>
class stackDerivedFromArrayList:private myArrayList<T>,public stackADT<T>{
public:
//直接调用myArrayList的构造函数 创建一个数组容量为10的数组
stackDerivedFromArrayList(int _initialCapacity=10):myArrayList<T>(_initialCapacity){
}
~stackDerivedFromArrayList(){
}
//其余拷贝控制成员使用合成的即可 它们会调用myArrayList的相应成员进行相应的操作
//...
//其余栈ADT的接口也通过直接调用myArrayList的共有方法来实现
bool empty()const {
return myArrayList<T>::empty(); }
int get_size()const {
return myArrayList<T>::get_size(); }
//在myArrayList中的get_element方法会对索引size-1进行检查而引发illegalParameterValue异常类
//但是在栈的用户角度并不能理解这个异常的意思 因此我们对top捕捉异常参数类重新抛出emptyStack异常类便于用户理解
T top()const {
try {
return myArrayList<T>::get_element(myArrayList<T>::get_size()-1);
}
catch (illegalParameterValue) {
throw stackEmpty();
}
}
void push(const T& _element) {
myArrayList<T>::insert(_element, myArrayList<T>::get_size());
}
void pop(