栈有后进先出(last in ,first out ,LIFO)的特性,即放到栈中的最后一个项目将第一个被删除。
定义栈的异常处理类:
#ifndef STACK_EXCEPTION_H_ #define STACK_EXCEPTION_H_ #include<stdexcept> #include<string> using namespace std; class stackException :public logic_error { stackException(const string &message="") :logic_error(message.c_str()) {} }; #endif栈基于数组的实现:header file stack_array.h
//the ADT stack is based on an array //header file stack_array.h for ADT stack //Arrary based implementation #ifndef STACK_ARRAY_H_ #define STACK_ARRAY_H_ #include"stack_exception.h" const int MAX=30; template<class T> class Stack { public: //constructor and destructor Stack();//default constructor //copy constructor and destructor are //supplied by teh compiler //stack operator bool isEmpty()const; //detemines whether the stack is empty //precondition :none //postcondition :return the true if the stack is empty //otherwise returns false void push(T newitem)throw(stackException); //adds an items to the top of a stack. //precondition :newitem is the item to be added. //postcondition :newitem is successful ,newitem is on //on the top of the stack. //Exception :throw exception if the newitem cannot be //placed on the stack. void pop()throw(stackException); //removes the top of a stack //precondition :none //postcondition :if the stack is not empty,the item //that was added most recently is removed ,however,if //the stack is empty ,deletion is impossible //Exception :Throws stackExceptaion if the stack is empty void pop(T&stacktop)throw(stackException); //retrieves and removes the top of a stack //precondition :none //postcondition :if stack is not empty stackTop //contains the item that was added most recently and //the item is impossible and stacktop is unchanged //Exception :throws stackexception if the stack is empty void getTop(T &stackTop)const throw(stackException); //retrieve the top of the stack //precondition :none //postcondition :if the stack is not empty, stackTOp //contains the item that was added most recently //however if the stack is empty ,the operation fails //and stacktop is unchanged the stacktop is unchanged //Exception :throw stackExcetpion the stack is empty private: T items[MAX]; int top; }; #endif #include"stack_array.h" template<class T> Stack<T>::Stack() { top=0; } template<class T> bool Stack<T>::isEmpty()const { return top==-1; } template<class T> void Stack<T>::push(T newitem)throw(stackException) { if(top>=MAX-1) throw stackException("stackException :push newitem failed !"); else { top++; items[top]=newitem; } } template<class T> void Stack<T>::pop()throw(stackException) { if(top<0) throw stackException("stackException :pop item faild !"); else --top; } template<class T> void Stack<T>::pop(T &stacktop)throw(stackException) { if(top<0) throw stackException("stackException :pop item failed !"); else { stacktop=items[top]; --top; } } template<class T> void Stack<T>::getTop(T&stackTop)const throw(stackException) { if(top<0) throw stackException("stackException :getTOp item failed !"); else stackTop=items[top]; }基于动态分配数组的实现:
基于指针的栈的实现:
#ifndef STACK_POINTER_H_ #define STACK_POINTER_H_ #include"stack_exception.h" template<class T> class Stack { public: //constructor and destructor Stack(); //default constructor Stack(const Stack &astack);//copy constructor ~Stack();//destructor //stack operations; bool isEmpty()const; void push(T newitem)throw(stackException); void pop()throw(stackException); void pop(T &stacktop)throw(stackException); void getTop(T & stacktop)const throw(stackException); private: struct stackNode { T item; stackNode *next; }; stackNode *topPtr; }; #endif #include"stack_pointer.h" #include<cstdlib> #include<cstddef> template<class T> Stack<T>::Stack() { } template<class T> Stack<T>::Stack(const Stack<T> &astack) { if(astack.topPtr==NULL) topPtr=NULL; else { topPtr=new stackNode; assert(topPtr!=NULL); stackNode *newPtr=topPtr; stackNode *tempPtr=astack.topPtr->next; topPtr->item=tempPtr->item; while(tempPtr!=NULL) { newPtr->next=new stackNode; assert(newPtr->next!=NULL); newPtr=newPtr->next; newPtr->item=tempPtr->item; tempPtr=tempPtr->next; } newPtr->next=NULL; } } template<class T> Stack<T>::~Stack() { while(!isEmpty()) pop(); } template<class T> bool Stack<T>::isEmpty()const { return topPtr==NULL; } template<class T> void Stack<T>::push(T newitem)throw(stackException) { stackNode newPtr=new stackNode; if(newPtr==NULL) throw stackException("stackExcepation :push item failed !"); else { newPtr->item=newitem; newPtr->next=topPtr; topPtr=newPtr; } } template<class T> void Stack<T>::pop()throw(stackException) { if(isEmpty()) throw stackException("stackException :pop the items failed !"); else { stackNode *tempPtr=topPtr; topPtr=topPtr->next; tempPtr->next=NULL; delete tempPtr; } } template<class T> void Stack<T>::pop(T &stacktop)throw(stackException) { if(isEmpty()) throw stackException("stackException :pop the items failed !"); else { stackNode *tempPtr=topPtr; stacktop=topPtr->item; topPtr=topPtr->next; tempPtr->next=NULL; delete tempPtr; } } template<class T> void Stack<T>::getTop(T & stacktop )const throw(stackException) { if(isEmpty()) throw stackException("stackException :getTOp item failed !"); else stacktop=topPtr->item; }基于ADT列表的栈的实现:
#ifndef STACK_ADT_H_ #define STACK_ADT_H_ #include<list> #include"stack_exception.h" using namespace std; template<class T> class Stack { public: //constructor and destructor Stack();//default constructor Stack(const Stack &astack);//copy constructor ~Stack(); bool isEmpty()const; void push(T newitem)throw(stackException); void pop()throw(stackException); void pop(T & topstack)throw(stackException); void getTop(T & topstack)throw(stackException); private: list<T> alist; }; #endif #include"stack_adt.h" template<class T> Stack<T>::Stack() { } template<class T> Stack<T>::Stack(const Stack<T> &astack) { alist=astack.alist; } template<class T> Stack<T>::~Stack<T>() { } template<class T> bool Stack<T>::isEmpty()const { return alist.empty(); } template<class T> void Stack<T>::push(T newitem)throw(stackException) { try{ alist.insert(1,newitem); } catch(...) { throw stackException("stackexception :push new item failed !"); } } template<class T> void Stack<T>::pop()throw(stackException) { try{ alist.remove(1); }catch(...) { throw stackException("stackexception :pop item failed !"); } } template<class T> void Stack<T>::pop(T &topstack)throw(stackException) { try{ alist.retrieve(1,topstack); alist.remove(1); }catch(...) { throw stackException("stackException :pop item failed !"); } } template<class T> void Stack<T>::getTop(T & topstack)throw(stackException) { try{ alist.retrieve(1,topstack); }catch(...) { throw stackException("stackException :getTop item failed !"); } }
栈的实现方式比较:
基于数组的实现使用静态分配内存,如果栈已满,则push操作无法将新项添加栈中。如果不能接受这个限制,则必须使用动态内存分配的数组或基于指针的实现。假定使用基于指针的实现,是选择使用链表实现还是选择使用ADT列表实现,使用ADT列表表示栈不如直接使用链表有效,而使用ADT列表可实现代码的重用,而且易于编写。